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 @@
+
+
+
+
+
+