44using System . Text ;
55using System . Text . Json ;
66using ModelContextProtocol . Utils ;
7+ using ModelContextProtocol . Utils . Json ;
78
89namespace ModelContextProtocol . Protocol . Auth ;
910
@@ -65,12 +66,12 @@ internal class AuthorizationService
6566 using var metadataResponse = await s_httpClient . GetAsync ( resourceMetadataUrl ) ;
6667 metadataResponse . EnsureSuccessStatusCode ( ) ;
6768
68- return await JsonSerializer . DeserializeAsync < ResourceMetadata > (
69- await metadataResponse . Content . ReadAsStreamAsync ( ) ,
70- new JsonSerializerOptions
71- {
72- PropertyNameCaseInsensitive = true
73- } ) ;
69+ var contentStream = await metadataResponse . Content . ReadAsStreamAsync ( ) ;
70+
71+ // Read as string first, then deserialize using source-generated serializer
72+ using var reader = new StreamReader ( contentStream ) ;
73+ var json = await reader . ReadToEndAsync ( ) ;
74+ return JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . ResourceMetadata ) ;
7475 }
7576 catch ( Exception )
7677 {
@@ -102,12 +103,19 @@ public static async Task<AuthorizationServerMetadata> DiscoverAuthorizationServe
102103 using var openIdResponse = await s_httpClient . GetAsync ( openIdConfigUrl ) ;
103104 if ( openIdResponse . IsSuccessStatusCode )
104105 {
105- return await JsonSerializer . DeserializeAsync < AuthorizationServerMetadata > (
106- await openIdResponse . Content . ReadAsStreamAsync ( ) ,
107- new JsonSerializerOptions
108- {
109- PropertyNameCaseInsensitive = true
110- } ) ?? throw new InvalidOperationException ( "Failed to parse authorization server metadata" ) ;
106+ var contentStream = await openIdResponse . Content . ReadAsStreamAsync ( ) ;
107+
108+ // Use source-generated serialization instead of dynamic deserialization
109+ using var reader = new StreamReader ( contentStream ) ;
110+ var json = await reader . ReadToEndAsync ( ) ;
111+ var result = JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . AuthorizationServerMetadata ) ;
112+
113+ if ( result == null )
114+ {
115+ throw new InvalidOperationException ( "Failed to parse authorization server metadata" ) ;
116+ }
117+
118+ return result ;
111119 }
112120 }
113121 catch ( Exception ex ) when ( ex is not InvalidOperationException )
@@ -122,12 +130,19 @@ await openIdResponse.Content.ReadAsStreamAsync(),
122130 using var oauthResponse = await s_httpClient . GetAsync ( oauthConfigUrl ) ;
123131 if ( oauthResponse . IsSuccessStatusCode )
124132 {
125- return await JsonSerializer . DeserializeAsync < AuthorizationServerMetadata > (
126- await oauthResponse . Content . ReadAsStreamAsync ( ) ,
127- new JsonSerializerOptions
128- {
129- PropertyNameCaseInsensitive = true
130- } ) ?? throw new InvalidOperationException ( "Failed to parse authorization server metadata" ) ;
133+ var contentStream = await oauthResponse . Content . ReadAsStreamAsync ( ) ;
134+
135+ // Use source-generated serialization instead of dynamic deserialization
136+ using var reader = new StreamReader ( contentStream ) ;
137+ var json = await reader . ReadToEndAsync ( ) ;
138+ var result = JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . AuthorizationServerMetadata ) ;
139+
140+ if ( result == null )
141+ {
142+ throw new InvalidOperationException ( "Failed to parse authorization server metadata" ) ;
143+ }
144+
145+ return result ;
131146 }
132147 }
133148 catch ( Exception ex ) when ( ex is not InvalidOperationException )
@@ -160,19 +175,25 @@ public static async Task<ClientRegistrationResponse> RegisterClientAsync(
160175 }
161176
162177 var content = new StringContent (
163- JsonSerializer . Serialize ( clientMetadata ) ,
178+ JsonSerializer . Serialize ( clientMetadata , McpJsonUtilities . JsonContext . Default . ClientMetadata ) ,
164179 Encoding . UTF8 ,
165180 "application/json" ) ;
166181
167182 using var response = await s_httpClient . PostAsync ( metadata . RegistrationEndpoint , content ) ;
168183 response . EnsureSuccessStatusCode ( ) ;
169184
170- return await JsonSerializer . DeserializeAsync < ClientRegistrationResponse > (
171- await response . Content . ReadAsStreamAsync ( ) ,
172- new JsonSerializerOptions
173- {
174- PropertyNameCaseInsensitive = true
175- } ) ?? throw new InvalidOperationException ( "Failed to parse client registration response" ) ;
185+ // Use source-generated serialization instead of dynamic deserialization
186+ var contentStream = await response . Content . ReadAsStreamAsync ( ) ;
187+ using var reader = new StreamReader ( contentStream ) ;
188+ var json = await reader . ReadToEndAsync ( ) ;
189+ var result = JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . ClientRegistrationResponse ) ;
190+
191+ if ( result == null )
192+ {
193+ throw new InvalidOperationException ( "Failed to parse client registration response" ) ;
194+ }
195+
196+ return result ;
176197 }
177198
178199 /// <summary>
@@ -293,12 +314,18 @@ public static async Task<TokenResponse> ExchangeCodeForTokensAsync(
293314 using var response = await s_httpClient . SendAsync ( request ) ;
294315 response . EnsureSuccessStatusCode ( ) ;
295316
296- return await JsonSerializer . DeserializeAsync < TokenResponse > (
297- await response . Content . ReadAsStreamAsync ( ) ,
298- new JsonSerializerOptions
299- {
300- PropertyNameCaseInsensitive = true
301- } ) ?? throw new InvalidOperationException ( "Failed to parse token response" ) ;
317+ // Use source-generated serialization instead of dynamic deserialization
318+ var contentStream = await response . Content . ReadAsStreamAsync ( ) ;
319+ using var reader = new StreamReader ( contentStream ) ;
320+ var json = await reader . ReadToEndAsync ( ) ;
321+ var result = JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . TokenResponse ) ;
322+
323+ if ( result == null )
324+ {
325+ throw new InvalidOperationException ( "Failed to parse token response" ) ;
326+ }
327+
328+ return result ;
302329 }
303330
304331 /// <summary>
@@ -341,12 +368,18 @@ public static async Task<TokenResponse> RefreshTokenAsync(
341368 using var response = await s_httpClient . SendAsync ( request ) ;
342369 response . EnsureSuccessStatusCode ( ) ;
343370
344- return await JsonSerializer . DeserializeAsync < TokenResponse > (
345- await response . Content . ReadAsStreamAsync ( ) ,
346- new JsonSerializerOptions
347- {
348- PropertyNameCaseInsensitive = true
349- } ) ?? throw new InvalidOperationException ( "Failed to parse token response" ) ;
371+ // Use source-generated serialization instead of dynamic deserialization
372+ var contentStream = await response . Content . ReadAsStreamAsync ( ) ;
373+ using var reader = new StreamReader ( contentStream ) ;
374+ var json = await reader . ReadToEndAsync ( ) ;
375+ var result = JsonSerializer . Deserialize ( json , McpJsonUtilities . JsonContext . Default . TokenResponse ) ;
376+
377+ if ( result == null )
378+ {
379+ throw new InvalidOperationException ( "Failed to parse token response" ) ;
380+ }
381+
382+ return result ;
350383 }
351384
352385 private static Dictionary < string , string > ParseAuthHeaderParameters ( string parameters )
0 commit comments