@@ -212,11 +212,6 @@ private async Task PerformOAuthAuthorizationAsync(
212212 // Get auth server metadata
213213 var authServerMetadata = await GetAuthServerMetadataAsync ( selectedAuthServer , cancellationToken ) . ConfigureAwait ( false ) ;
214214
215- if ( authServerMetadata is null )
216- {
217- ThrowFailedToHandleUnauthorizedResponse ( $ "Failed to retrieve metadata for authorization server: '{ selectedAuthServer } '") ;
218- }
219-
220215 // Store auth server metadata for future refresh operations
221216 _authServerMetadata = authServerMetadata ;
222217
@@ -238,7 +233,7 @@ private async Task PerformOAuthAuthorizationAsync(
238233 LogOAuthAuthorizationCompleted ( ) ;
239234 }
240235
241- private async Task < AuthorizationServerMetadata ? > GetAuthServerMetadataAsync ( Uri authServerUri , CancellationToken cancellationToken )
236+ private async Task < AuthorizationServerMetadata > GetAuthServerMetadataAsync ( Uri authServerUri , CancellationToken cancellationToken )
242237 {
243238 if ( ! authServerUri . OriginalString . EndsWith ( "/" ) )
244239 {
@@ -249,7 +244,9 @@ private async Task PerformOAuthAuthorizationAsync(
249244 {
250245 try
251246 {
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 ) ;
253250 if ( ! response . IsSuccessStatusCode )
254251 {
255252 continue ;
@@ -258,23 +255,36 @@ private async Task PerformOAuthAuthorizationAsync(
258255 using var stream = await response . Content . ReadAsStreamAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
259256 var metadata = await JsonSerializer . DeserializeAsync ( stream , McpJsonUtilities . JsonContext . Default . AuthorizationServerMetadata , cancellationToken ) . ConfigureAwait ( false ) ;
260257
261- if ( metadata != null )
258+ if ( metadata is null )
259+ {
260+ continue ;
261+ }
262+
263+ if ( metadata . AuthorizationEndpoint is null )
262264 {
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+ }
267267
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.") ;
269272 }
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 ;
270280 }
271281 catch ( Exception ex )
272282 {
273283 LogErrorFetchingAuthServerMetadata ( ex , path ) ;
274284 }
275285 }
276286
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 } '" ) ;
278288 }
279289
280290 private async Task < TokenContainer > RefreshTokenAsync ( string refreshToken , Uri resourceUri , AuthorizationServerMetadata authServerMetadata , CancellationToken cancellationToken )
@@ -320,12 +330,6 @@ private Uri BuildAuthorizationUrl(
320330 AuthorizationServerMetadata authServerMetadata ,
321331 string codeChallenge )
322332 {
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-
329333 var queryParamsDictionary = new Dictionary < string , string >
330334 {
331335 [ "client_id" ] = GetClientIdOrThrow ( ) ,
0 commit comments