From 1562d5be3be50c8d2db7db903987c6b8cdb1de6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 12 Mar 2024 18:06:13 +0100 Subject: [PATCH] Add Wikimedia to the list of supported providers --- .../OpenIddictClientAspNetCoreHandlers.cs | 6 +- ...ctClientWebIntegrationHandlers.Userinfo.cs | 59 +++++++++++++++++-- ...penIddictClientWebIntegrationProviders.xml | 21 +++++++ 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs index a020baaa..d3fbef02 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs @@ -425,7 +425,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers throw new InvalidOperationException(SR.GetResourceString(SR.ID0354)); } - // Resolve the cookie builder from the OWIN integration options. + // Resolve the cookie builder from the ASP.NET Core integration options. var builder = _options.CurrentValue.CookieBuilder; // Compute the name of the cookie name based on the prefix and the random nonce. @@ -741,7 +741,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers var response = context.Transaction.GetHttpRequest()?.HttpContext.Response ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); - // Resolve the cookie builder from the OWIN integration options. + // Resolve the cookie builder from the ASP.NET Core integration options. var builder = _options.CurrentValue.CookieBuilder; // Unless a value was explicitly set in the options, use the expiration date @@ -980,7 +980,7 @@ public static partial class OpenIddictClientAspNetCoreHandlers var response = context.Transaction.GetHttpRequest()?.HttpContext.Response ?? throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); - // Resolve the cookie builder from the OWIN integration options. + // Resolve the cookie builder from the ASP.NET Core integration options. var builder = _options.CurrentValue.CookieBuilder; // Unless a value was explicitly set in the options, use the expiration date diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs index 0d42ede3..2c0d3100 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs @@ -35,7 +35,8 @@ public static partial class OpenIddictClientWebIntegrationHandlers * Userinfo response extraction: */ NormalizeContentType.Descriptor, - UnwrapUserinfoResponse.Descriptor + UnwrapUserinfoResponse.Descriptor, + MapNonStandardResponseParameters.Descriptor, ]); /// @@ -323,10 +324,22 @@ public static partial class OpenIddictClientWebIntegrationHandlers response.Content.Headers.ContentType = context.Registration.ProviderType switch { // Mixcloud returns JSON-formatted contents declared as "text/javascript". - ProviderTypes.Mixcloud => new MediaTypeHeaderValue(MediaTypes.Json) - { - CharSet = Charsets.Utf8 - }, + ProviderTypes.Mixcloud when string.Equals( + response.Content.Headers.ContentType?.MediaType, + "text/javascript", StringComparison.OrdinalIgnoreCase) + => new MediaTypeHeaderValue(MediaTypes.Json) + { + CharSet = Charsets.Utf8 + }, + + // Wikimedia returns JSON-formatted contents declared as "text/html". + ProviderTypes.Wikimedia when string.Equals( + response.Content.Headers.ContentType?.MediaType, + "text/html", StringComparison.OrdinalIgnoreCase) + => new MediaTypeHeaderValue(MediaTypes.Json) + { + CharSet = Charsets.Utf8 + }, _ => response.Content.Headers.ContentType }; @@ -429,5 +442,41 @@ public static partial class OpenIddictClientWebIntegrationHandlers return default; } } + + /// + /// Contains the logic responsible for mapping non-standard response parameters + /// to their standard equivalent for the providers that require it. + /// + public sealed class MapNonStandardResponseParameters : IOpenIddictClientHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictClientHandlerDescriptor Descriptor { get; } + = OpenIddictClientHandlerDescriptor.CreateBuilder() + .UseSingletonHandler() + .SetOrder(UnwrapUserinfoResponse.Descriptor.Order + 1_000) + .SetType(OpenIddictClientHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(ExtractUserinfoResponseContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + Debug.Assert(context.Response is not null, SR.GetResourceString(SR.ID4007)); + + // Note: Wikimedia returns a non-standard "sub" claim formatted as an integer instead of a string. + if (context.Registration.ProviderType is ProviderTypes.Wikimedia) + { + context.Response[Claims.Subject] = (string?) context.Response[Claims.Subject]; + } + + return default; + } + } } } diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml index 0342765a..ef9c16b1 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml @@ -1765,6 +1765,27 @@ + + + + + + + + + + + +