diff --git a/guides/contributing-a-new-web-provider.html b/guides/contributing-a-new-web-provider.html index a63b980..da81839 100644 --- a/guides/contributing-a-new-web-provider.html +++ b/guides/contributing-a-new-web-provider.html @@ -218,11 +218,70 @@ 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> +
If the provider returns wrapped or nested userinfo responses (e.g under a response
or data
node), the UnwrapUserinfoResponse
handler in
+OpenIddictClientWebIntegrationHandlers.Userinfo.cs
+must be updated to unwrap the userinfo payload and allow OpenIddict to map them to flat CLR Claim
instances:
/// <summary>
+/// Contains the logic responsible for extracting the userinfo response
+/// from nested JSON nodes (e.g "data") for the providers that require it.
+/// </summary>
+public sealed class UnwrapUserinfoResponse : IOpenIddictClientHandler<ExtractUserinfoResponseContext>
+{
+ /// <summary>
+ /// Gets the default descriptor definition assigned to this handler.
+ /// </summary>
+ public static OpenIddictClientHandlerDescriptor Descriptor { get; }
+ = OpenIddictClientHandlerDescriptor.CreateBuilder<ExtractUserinfoResponseContext>()
+ .UseSingletonHandler<UnwrapUserinfoResponse>()
+ .SetOrder(int.MaxValue - 50_000)
+ .SetType(OpenIddictClientHandlerType.BuiltIn)
+ .Build();
+
+ /// <inheritdoc/>
+ public ValueTask HandleAsync(ExtractUserinfoResponseContext context)
+ {
+ if (context is null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ context.Response = context.Registration.ProviderType switch
+ {
+ // Fitbit returns a nested "user" object.
+ ProviderTypes.Fitbit => new(context.Response["user"]?.GetNamedParameters() ??
+ throw new InvalidOperationException(SR.FormatID0334("user"))),
+
+ // StackExchange returns an "items" array containing a single element.
+ ProviderTypes.StackExchange => new(context.Response["items"]?[0]?.GetNamedParameters() ??
+ throw new InvalidOperationException(SR.FormatID0334("items/0"))),
+
+ // SubscribeStar returns a nested "user" object that is itself nested in a GraphQL "data" node.
+ ProviderTypes.SubscribeStar => new(context.Response["data"]?["user"]?.GetNamedParameters() ??
+ throw new InvalidOperationException(SR.FormatID0334("data/user"))),
+
+ _ => context.Response
+ };
+
+ return default;
+ }
+}
+
If you're unsure whether the provider returns wrapped responses or not, the +received payload can be found in the logs after a successful authorization flow:
+OpenIddict.Client.OpenIddictClientDispatcher: Information: The userinfo response returned by https://contoso.com/users/me was successfully extracted: {
+ "data": {
+ "username": "odile.donat",
+ "name": "Odile Donat",
+ "email": "odile.donat@fabrikam.com"
+ }
+}.
+
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:
MapCustomWebServicesFederationClaims
event handler in
+OpenIddictClientWebIntegrationHandlers.cs
+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.
diff --git a/index.html b/index.html
index d6bc95a..6b16528 100644
--- a/index.html
+++ b/index.html
@@ -264,7 +264,7 @@ To reference the OpenIddict MyGet feed, create a NuGet.configOpenIddict is actively maintained by Kévin Chalet. Contributions are welcome and can be submitted using pull requests.
Special thanks to our sponsors for their incredible support:
-
+
License
This project is licensed under the Apache License. This means that you can use, modify and distribute it freely.
diff --git a/manifest.json b/manifest.json
index 4c01cbc..15648b0 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1600,7 +1600,7 @@
"output": {
".html": {
"relative_path": "guides/contributing-a-new-web-provider.html",
- "hash": "TVxxQxHBmAEQiyh1LF4KZQ=="
+ "hash": "zn6aU7/pypsyz6PAQMbGbw=="
}
},
"is_incremental": false,
@@ -1694,7 +1694,7 @@
"output": {
".html": {
"relative_path": "index.html",
- "hash": "aSgtFSzx/YtktQZx5WGJDg=="
+ "hash": "JrsiUi4UaF8z/3YY6GZfcQ=="
}
},
"is_incremental": false,