From a25cb52830199f5b211252a55b3c1c9dcdc53de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Mon, 18 Apr 2022 19:16:40 +0200 Subject: [PATCH] Don't throw an exception if the address of the userinfo endpoint is not available --- .../OpenIddictResources.resx | 6 --- .../OpenIddictClientHandlers.cs | 49 ++++++++++++++----- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/OpenIddict.Abstractions/OpenIddictResources.resx b/src/OpenIddict.Abstractions/OpenIddictResources.resx index 525ba8aa..0f7f2535 100644 --- a/src/OpenIddict.Abstractions/OpenIddictResources.resx +++ b/src/OpenIddict.Abstractions/OpenIddictResources.resx @@ -1668,12 +1668,6 @@ To register the server services, use 'services.AddOpenIddict().AddClient()'. The issuer should be a valid absolute URL at this point. - - The token endpoint should be a valid absolute URL at this point. - - - The userinfo endpoint should be a valid absolute URL at this point. - An error occurred while validating the token '{Token}'. diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.cs index 7599fa43..5376ca6d 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.cs @@ -1426,16 +1426,27 @@ public static partial class OpenIddictClientHandlers /// public async ValueTask HandleAsync(ProcessAuthenticationContext context!!) { + if (!context.ExtractBackchannelAccessToken && + !context.ExtractBackchannelIdentityToken && + !context.ExtractRefreshToken) + { + return; + } + var configuration = await context.Registration.ConfigurationManager.GetConfigurationAsync(default) ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0140)); - if (configuration.TokenEndpoint is not { IsAbsoluteUri: true } || - !configuration.TokenEndpoint.IsWellFormedOriginalString()) + // Ensure the issuer resolved from the configuration matches the expected value. + if (configuration.Issuer != context.Issuer) { - throw new InvalidOperationException(SR.FormatID0301(Metadata.TokenEndpoint)); + throw new InvalidOperationException(SR.GetResourceString(SR.ID0307)); } - context.TokenEndpoint = configuration.TokenEndpoint; + // Try to extract the address of the token endpoint from the server configuration. + if (configuration.TokenEndpoint is { IsAbsoluteUri: true }) + { + context.TokenEndpoint = configuration.TokenEndpoint; + } } } @@ -1534,10 +1545,15 @@ public static partial class OpenIddictClientHandlers /// public async ValueTask HandleAsync(ProcessAuthenticationContext context!!) { - Debug.Assert(context.TokenEndpoint is { IsAbsoluteUri: true } endpoint && - endpoint.IsWellFormedOriginalString(), SR.GetResourceString(SR.ID4014)); Debug.Assert(context.TokenRequest is not null, SR.GetResourceString(SR.ID4008)); + // Ensure the token endpoint is present and is a valid absolute URL. + if (context.TokenEndpoint is not { IsAbsoluteUri: true } || + !context.TokenEndpoint.IsWellFormedOriginalString()) + { + throw new InvalidOperationException(SR.FormatID0301(Metadata.TokenEndpoint)); + } + context.TokenResponse = await _service.SendTokenRequestAsync( context.Registration, context.TokenEndpoint, context.TokenRequest); } @@ -2236,13 +2252,17 @@ public static partial class OpenIddictClientHandlers var configuration = await context.Registration.ConfigurationManager.GetConfigurationAsync(default) ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0140)); - if (configuration.UserinfoEndpoint is not { IsAbsoluteUri: true } || - !configuration.UserinfoEndpoint.IsWellFormedOriginalString()) + // Ensure the issuer resolved from the configuration matches the expected value. + if (configuration.Issuer != context.Issuer) { - throw new InvalidOperationException(SR.FormatID0301(Metadata.UserinfoEndpoint)); + throw new InvalidOperationException(SR.GetResourceString(SR.ID0307)); } - context.UserinfoEndpoint = configuration.UserinfoEndpoint; + // Try to extract the address of the userinfo endpoint from the server configuration. + if (configuration.UserinfoEndpoint is { IsAbsoluteUri: true }) + { + context.UserinfoEndpoint = configuration.UserinfoEndpoint; + } } } @@ -2360,10 +2380,15 @@ public static partial class OpenIddictClientHandlers /// public async ValueTask HandleAsync(ProcessAuthenticationContext context!!) { - Debug.Assert(context.UserinfoEndpoint is { IsAbsoluteUri: true } endpoint && - endpoint.IsWellFormedOriginalString(), SR.GetResourceString(SR.ID4015)); Debug.Assert(context.UserinfoRequest is not null, SR.GetResourceString(SR.ID4008)); + // Ensure the userinfo endpoint is present and is a valid absolute URL. + if (context.UserinfoEndpoint is not { IsAbsoluteUri: true } || + !context.UserinfoEndpoint.IsWellFormedOriginalString()) + { + throw new InvalidOperationException(SR.FormatID0301(Metadata.UserinfoEndpoint)); + } + // Note: userinfo responses can be of two types: // - application/json responses containing a JSON object listing the user claims as-is. // - application/jwt responses containing a signed/encrypted JSON Web Token containing the user claims.