From 41e4ef6bbcc1d3c4115ae9218d1a9d1de0dab755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 13 Oct 2022 18:59:23 +0200 Subject: [PATCH] Change how additional userinfo parameters are handled by the Web providers --- ...ctClientWebIntegrationHandlers.Userinfo.cs | 59 ++----------------- .../OpenIddictClientWebIntegrationHandlers.cs | 44 ++++++++++++++ 2 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs index 593d6e38..f8dc287b 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Userinfo.cs @@ -7,8 +7,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Text.Json; -using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers; -using static OpenIddict.Client.SystemNetHttp.OpenIddictClientSystemNetHttpHandlers.Userinfo; +using static OpenIddict.Client.OpenIddictClientHandlers.Userinfo; using static OpenIddict.Client.WebIntegration.OpenIddictClientWebIntegrationConstants; namespace OpenIddict.Client.WebIntegration; @@ -18,75 +17,29 @@ public static partial class OpenIddictClientWebIntegrationHandlers public static class Userinfo { public static ImmutableArray DefaultHandlers { get; } = ImmutableArray.Create( - /* - * Userinfo request preparation: - */ - AttachAdditionalParameters.Descriptor, - /* * Userinfo response extraction: */ UnwrapUserinfoResponse.Descriptor); - /// - /// Contains the logic responsible for attaching additional parameters for the providers that require it. - /// - public class AttachAdditionalParameters : IOpenIddictClientHandler - { - /// - /// Gets the default descriptor definition assigned to this handler. - /// - public static OpenIddictClientHandlerDescriptor Descriptor { get; } - = OpenIddictClientHandlerDescriptor.CreateBuilder() - .UseSingletonHandler() - .SetOrder(PrepareGetHttpRequest.Descriptor.Order - 500) - .SetType(OpenIddictClientHandlerType.BuiltIn) - .Build(); - - /// - public ValueTask HandleAsync(PrepareUserinfoRequestContext context) - { - if (context is null) - { - throw new ArgumentNullException(nameof(context)); - } - - Debug.Assert(context.Request is not null, SR.GetResourceString(SR.ID4008)); - - if (context.Registration.ProviderName is Providers.Twitter) - { - var options = context.Registration.GetTwitterOptions(); - - // Twitter limits the number of fields returned by the userinfo endpoint - // but allows returning additional information using special parameters that - // determine what fields will be returned as part of the userinfo response. - context.Request["expansions"] = string.Join(",", options.Expansions); - context.Request["tweet.fields"] = string.Join(",", options.TweetFields); - context.Request["user.fields"] = string.Join(",", options.UserFields); - } - - return default; - } - } - /// /// Contains the logic responsible for extracting the userinfo response /// from nested JSON nodes (e.g "data") for the providers that require it. /// - public class UnwrapUserinfoResponse : IOpenIddictClientHandler + public class UnwrapUserinfoResponse : IOpenIddictClientHandler { /// /// Gets the default descriptor definition assigned to this handler. /// public static OpenIddictClientHandlerDescriptor Descriptor { get; } - = OpenIddictClientHandlerDescriptor.CreateBuilder() + = OpenIddictClientHandlerDescriptor.CreateBuilder() .UseSingletonHandler() - .SetOrder(ExtractJsonHttpResponse.Descriptor.Order + 500) + .SetOrder(PopulateClaims.Descriptor.Order - 500) .SetType(OpenIddictClientHandlerType.BuiltIn) .Build(); /// - public ValueTask HandleAsync(ExtractUserinfoResponseContext context) + public ValueTask HandleAsync(HandleUserinfoResponseContext context) { if (context is null) { @@ -102,7 +55,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers context.Response = context.Registration.ProviderName switch { - // Twitter uses a nested object. + // Twitter returns a nested "data" object. Providers.Twitter => (JsonElement) context.Response["data"] is { ValueKind: JsonValueKind.Object } element ? new(element) : throw new InvalidOperationException(SR.FormatID0334("data")), diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs index 603b745e..dfc6b803 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs @@ -21,6 +21,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers */ AttachNonStandardClientAssertionTokenClaims.Descriptor, AttachTokenRequestNonStandardClientCredentials.Descriptor, + AttachAdditionalUserinfoRequestParameters.Descriptor, /* * Challenge processing: @@ -120,6 +121,49 @@ public static partial class OpenIddictClientWebIntegrationHandlers } } + /// + /// Contains the logic responsible for attaching additional parameters + /// to the userinfo request for the providers that require it. + /// + public class AttachAdditionalUserinfoRequestParameters : IOpenIddictClientHandler + { + /// + /// Gets the default descriptor definition assigned to this handler. + /// + public static OpenIddictClientHandlerDescriptor Descriptor { get; } + = OpenIddictClientHandlerDescriptor.CreateBuilder() + .AddFilter() + .UseSingletonHandler() + .SetOrder(AttachUserinfoRequestParameters.Descriptor.Order + 500) + .SetType(OpenIddictClientHandlerType.BuiltIn) + .Build(); + + /// + public ValueTask HandleAsync(ProcessAuthenticationContext context) + { + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } + + Debug.Assert(context.UserinfoRequest is not null, SR.GetResourceString(SR.ID4008)); + + if (context.Registration.ProviderName is Providers.Twitter) + { + var options = context.Registration.GetTwitterOptions(); + + // Twitter limits the number of fields returned by the userinfo endpoint + // but allows returning additional information using special parameters that + // determine what fields will be returned as part of the userinfo response. + context.UserinfoRequest["expansions"] = string.Join(",", options.Expansions); + context.UserinfoRequest["tweet.fields"] = string.Join(",", options.TweetFields); + context.UserinfoRequest["user.fields"] = string.Join(",", options.UserFields); + } + + return default; + } + } + /// /// Contains the logic responsible for attaching a specific response mode for providers that require it. ///