@@ -212,11 +212,6 @@ private async Task PerformOAuthAuthorizationAsync(
212
212
// Get auth server metadata
213
213
var authServerMetadata = await GetAuthServerMetadataAsync ( selectedAuthServer , cancellationToken ) . ConfigureAwait ( false ) ;
214
214
215
- if ( authServerMetadata is null )
216
- {
217
- ThrowFailedToHandleUnauthorizedResponse ( $ "Failed to retrieve metadata for authorization server: '{ selectedAuthServer } '") ;
218
- }
219
-
220
215
// Store auth server metadata for future refresh operations
221
216
_authServerMetadata = authServerMetadata ;
222
217
@@ -238,7 +233,7 @@ private async Task PerformOAuthAuthorizationAsync(
238
233
LogOAuthAuthorizationCompleted ( ) ;
239
234
}
240
235
241
- private async Task < AuthorizationServerMetadata ? > GetAuthServerMetadataAsync ( Uri authServerUri , CancellationToken cancellationToken )
236
+ private async Task < AuthorizationServerMetadata > GetAuthServerMetadataAsync ( Uri authServerUri , CancellationToken cancellationToken )
242
237
{
243
238
if ( ! authServerUri . OriginalString . EndsWith ( "/" ) )
244
239
{
@@ -249,7 +244,9 @@ private async Task PerformOAuthAuthorizationAsync(
249
244
{
250
245
try
251
246
{
252
- var response = await _httpClient . GetAsync ( new Uri ( authServerUri , path ) , cancellationToken ) . ConfigureAwait ( false ) ;
247
+ var wellKnownEndpoint = new Uri ( authServerUri , path ) ;
248
+
249
+ var response = await _httpClient . GetAsync ( wellKnownEndpoint , cancellationToken ) . ConfigureAwait ( false ) ;
253
250
if ( ! response . IsSuccessStatusCode )
254
251
{
255
252
continue ;
@@ -258,23 +255,36 @@ private async Task PerformOAuthAuthorizationAsync(
258
255
using var stream = await response . Content . ReadAsStreamAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
259
256
var metadata = await JsonSerializer . DeserializeAsync ( stream , McpJsonUtilities . JsonContext . Default . AuthorizationServerMetadata , cancellationToken ) . ConfigureAwait ( false ) ;
260
257
261
- if ( metadata != null )
258
+ if ( metadata is null )
259
+ {
260
+ continue ;
261
+ }
262
+
263
+ if ( metadata . AuthorizationEndpoint is null )
262
264
{
263
- metadata . ResponseTypesSupported ??= [ "code" ] ;
264
- metadata . GrantTypesSupported ??= [ "authorization_code" , "refresh_token" ] ;
265
- metadata . TokenEndpointAuthMethodsSupported ??= [ "client_secret_post" ] ;
266
- metadata . CodeChallengeMethodsSupported ??= [ "S256" ] ;
265
+ ThrowFailedToHandleUnauthorizedResponse ( $ "No authorization_endpoint was provided via '{ wellKnownEndpoint } '.") ;
266
+ }
267
267
268
- return metadata ;
268
+ if ( metadata . AuthorizationEndpoint . Scheme != Uri . UriSchemeHttp &&
269
+ metadata . AuthorizationEndpoint . Scheme != Uri . UriSchemeHttps )
270
+ {
271
+ ThrowFailedToHandleUnauthorizedResponse ( $ "AuthorizationEndpoint must use HTTP or HTTPS. '{ metadata . AuthorizationEndpoint } ' does not meet this requirement.") ;
269
272
}
273
+
274
+ metadata . ResponseTypesSupported ??= [ "code" ] ;
275
+ metadata . GrantTypesSupported ??= [ "authorization_code" , "refresh_token" ] ;
276
+ metadata . TokenEndpointAuthMethodsSupported ??= [ "client_secret_post" ] ;
277
+ metadata . CodeChallengeMethodsSupported ??= [ "S256" ] ;
278
+
279
+ return metadata ;
270
280
}
271
281
catch ( Exception ex )
272
282
{
273
283
LogErrorFetchingAuthServerMetadata ( ex , path ) ;
274
284
}
275
285
}
276
286
277
- return null ;
287
+ throw new McpException ( $ "Failed to find .well-known/openid-configuration or .well-known/oauth-authorization-server metadata for authorization server: ' { authServerUri } '" ) ;
278
288
}
279
289
280
290
private async Task < TokenContainer > RefreshTokenAsync ( string refreshToken , Uri resourceUri , AuthorizationServerMetadata authServerMetadata , CancellationToken cancellationToken )
@@ -320,12 +330,6 @@ private Uri BuildAuthorizationUrl(
320
330
AuthorizationServerMetadata authServerMetadata ,
321
331
string codeChallenge )
322
332
{
323
- if ( authServerMetadata . AuthorizationEndpoint . Scheme != Uri . UriSchemeHttp &&
324
- authServerMetadata . AuthorizationEndpoint . Scheme != Uri . UriSchemeHttps )
325
- {
326
- throw new ArgumentException ( "AuthorizationEndpoint must use HTTP or HTTPS." , nameof ( authServerMetadata ) ) ;
327
- }
328
-
329
333
var queryParamsDictionary = new Dictionary < string , string >
330
334
{
331
335
[ "client_id" ] = GetClientIdOrThrow ( ) ,
0 commit comments