From 5a02224f34c9b4efd21dae55dc563c369f8c1905 Mon Sep 17 00:00:00 2001 From: OpenIddict Bot <32257313+openiddict-bot@users.noreply.github.com> Date: Tue, 1 Aug 2023 13:46:50 +0000 Subject: [PATCH] Update the documentation pages --- guides/contributing-a-new-web-provider.html | 59 ++++++++++++++++++++- manifest.json | 2 +- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/guides/contributing-a-new-web-provider.html b/guides/contributing-a-new-web-provider.html index 1104af8..a63b980 100644 --- a/guides/contributing-a-new-web-provider.html +++ b/guides/contributing-a-new-web-provider.html @@ -218,7 +218,64 @@ store the tenant name. Once added, the URIs can include a placeholder of the sam Description="The tenant used to identify the Zendesk instance" /> </Provider> -
ClaimTypes
equivalentIf the provider doesn't return an id_token
and doesn't offer a standard userinfo endpoint, it is likely it uses custom parameters
+to represent things like the user identifier. If so, update the MapCustomWebServicesFederationClaims
event handler to map these
+parameters to the usual WS-Federation claims exposed by the .NET BCL ClaimTypes
class, which simplifies integration with libraries
+like ASP.NET Core Identity:
/// <summary>
+/// Contains the logic responsible for mapping select custom claims to
+/// their WS-Federation equivalent for the providers that require it.
+/// </summary>
+public sealed class MapCustomWebServicesFederationClaims : IOpenIddictClientHandler<ProcessAuthenticationContext>
+{
+ /// <summary>
+ /// Gets the default descriptor definition assigned to this handler.
+ /// </summary>
+ public static OpenIddictClientHandlerDescriptor Descriptor { get; }
+ = OpenIddictClientHandlerDescriptor.CreateBuilder<ProcessAuthenticationContext>()
+ .AddFilter<RequireWebServicesFederationClaimMappingEnabled>()
+ .UseSingletonHandler<MapCustomWebServicesFederationClaims>()
+ .SetOrder(MapStandardWebServicesFederationClaims.Descriptor.Order + 1_000)
+ .SetType(OpenIddictClientHandlerType.BuiltIn)
+ .Build();
+
+ /// <inheritdoc/>
+ public ValueTask HandleAsync(ProcessAuthenticationContext context)
+ {
+ if (context is null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ context.MergedPrincipal.SetClaim(ClaimTypes.Email, context.Registration.ProviderType switch
+ {
+ // ServiceChannel returns the user identifier as a custom "Email" node:
+ ProviderTypes.ServiceChannel => (string?) context.UserinfoResponse?["Email"],
+
+ _ => context.MergedPrincipal.GetClaim(ClaimTypes.Email)
+ });
+
+ context.MergedPrincipal.SetClaim(ClaimTypes.Name, context.Registration.ProviderType switch
+ {
+ // ServiceChannel returns the user identifier as a custom "UserName" node:
+ ProviderTypes.ServiceChannel => (string?) context.UserinfoResponse?["UserName"],
+
+ _ => context.MergedPrincipal.GetClaim(ClaimTypes.Name)
+ });
+
+ context.MergedPrincipal.SetClaim(ClaimTypes.NameIdentifier, context.Registration.ProviderType switch
+ {
+ // ServiceChannel returns the user identifier as a custom "UserId" node:
+ ProviderTypes.ServiceChannel => (string?) context.UserinfoResponse?["UserId"],
+
+ _ => context.MergedPrincipal.GetClaim(ClaimTypes.NameIdentifier)
+ });
+
+ return default;
+ }
+}
+
If the targeted service is fully standard-compliant, no additional configuration should be required at this point.
To confirm it, build the solution and add an instance of the new provider to the OpenIddict.Sandbox.AspNetCore.Client
sandbox: