From 861c7bc1372cdc90e8f3e7ef96bfed6c8d69ee48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sat, 11 Jul 2026 19:24:44 +0200 Subject: [PATCH] Add Vercel to the list of supported providers --- .../OpenIddictHelpers.cs | 12 ------ ...enIddictClientSystemIntegrationHandlers.cs | 4 +- ...penIddictClientSystemIntegrationMarshal.cs | 8 ++-- ...tClientWebIntegrationHandlers.Discovery.cs | 41 ++++++++++++++++++- ...penIddictClientWebIntegrationProviders.xml | 31 ++++++++++---- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs index 3d814499..f7dd1287 100644 --- a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs +++ b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs @@ -85,18 +85,6 @@ internal static class OpenIddictHelpers } } - /// - /// Computes an absolute URI from the specified and URIs. - /// Note: if the URI is already absolute, it is directly returned. - /// - /// The left part. - /// The right part. - /// An absolute URI from the specified and . - /// is not an absolute URI. - [return: NotNullIfNotNull(nameof(right))] - public static Uri? CreateAbsoluteUri(Uri? left, string? right) - => CreateAbsoluteUri(left, !string.IsNullOrEmpty(right) ? new Uri(right, UriKind.RelativeOrAbsolute) : null); - /// /// Computes an absolute URI from the specified and URIs. /// Note: if the URI is already absolute, it is directly returned. diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs index 9b619793..309c7c6c 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs @@ -1236,7 +1236,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers // Ensure the authentication demand is tracked by the OpenIddict client system integration // marshal and resolve the corresponding request forgery protection. If it can't be found, // this may indicate a session fixation attack: in this case, reject the authentication demand. - if (!_marshal.TryGetRequestForgeryProtection(context.Nonce, out string? protection)) + if (!_marshal.TryGetRequestForgeryProtection(context.Nonce, out string? result)) { context.Reject( error: Errors.InvalidRequest, @@ -1246,7 +1246,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers return ValueTask.CompletedTask; } - context.RequestForgeryProtection = protection; + context.RequestForgeryProtection = result; return ValueTask.CompletedTask; } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs index 6584c090..b8dbc371 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs @@ -115,19 +115,19 @@ public sealed class OpenIddictClientSystemIntegrationMarshal /// Tries to resolve the request forgery protection associated with the specified authentication demand. /// /// The nonce, used as a unique identifier. - /// The request forgery protection associated with the specified authentication demand. + /// The request forgery protection associated with the specified authentication demand. /// if the operation could be validated, otherwise. - internal bool TryGetRequestForgeryProtection(string nonce, [NotNullWhen(true)] out string? protection) + internal bool TryGetRequestForgeryProtection(string nonce, [NotNullWhen(true)] out string? result) { ArgumentException.ThrowIfNullOrEmpty(nonce); if (_tracker.TryGetValue(nonce, out var operation)) { - protection = operation.Value.RequestForgeryProtection; + result = operation.Value.RequestForgeryProtection; return true; } - protection = null; + result = null; return false; } diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs index d85628e1..c80b4abb 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs @@ -21,6 +21,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers */ AmendIssuer.Descriptor, AmendGrantTypes.Descriptor, + AmendResponseModes.Descriptor, AmendCodeChallengeMethods.Descriptor, AmendScopes.Descriptor, AmendClientAuthenticationMethods.Descriptor, @@ -157,6 +158,42 @@ public static partial class OpenIddictClientWebIntegrationHandlers } } + /// + /// Contains the logic responsible for amending the supported response modes for the providers that require it. + /// + public sealed class AmendResponseModes : IOpenIddictClientHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictClientHandlerDescriptor Descriptor { get; } + = OpenIddictClientHandlerDescriptor.CreateBuilder() + .UseSingletonHandler() + .SetOrder(ExtractGrantTypes.Descriptor.Order + 500) + .SetType(OpenIddictClientHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(HandleConfigurationResponseContext context) + { + ArgumentNullException.ThrowIfNull(context); + + // Note: some providers don't list the response modes they support, which prevents the OpenIddict + // client from using them (unless they are assumed to be enabled by default, like the query or + // fragment response modes). To work around that, the list of supported response modes is amended + // to include the known supported modes for the providers that require it. + + // Note: Vercel supports the "query" response mode but exclusively lists + // the "web_message.opener" mode in its server configuration metadata. + if (context.Registration.ProviderType is ProviderTypes.Vercel) + { + context.Configuration.ResponseModesSupported.Add(ResponseModes.Query); + } + + return ValueTask.CompletedTask; + } + } + /// /// Contains the logic responsible for amending the supported /// code challenge methods for the providers that require it. @@ -169,7 +206,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers public static OpenIddictClientHandlerDescriptor Descriptor { get; } = OpenIddictClientHandlerDescriptor.CreateBuilder() .UseSingletonHandler() - .SetOrder(ExtractCodeChallengeMethods.Descriptor.Order + 500) + .SetOrder(AmendResponseModes.Descriptor.Order + 500) .SetType(OpenIddictClientHandlerType.BuiltIn) .Build(); @@ -395,7 +432,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers else if (context.Registration.ProviderType is ProviderTypes.Auth0) { context.Configuration.EndSessionEndpoint ??= OpenIddictHelpers.CreateAbsoluteUri( - context.Registration.Issuer, "oidc/logout"); + context.Registration.Issuer, new Uri("oidc/logout", UriKind.Relative)); } // While Huawei supports OpenID Connect discovery, the configuration diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml index 4018dc5b..47f3ff7f 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml @@ -798,9 +798,9 @@ - + @@ -1517,9 +1517,9 @@ --> - + @@ -1696,9 +1696,9 @@ - + @@ -2538,6 +2538,19 @@ + + + + + +