|
|
|
@@ -116,7 +116,8 @@ the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn't s
|
|
|
|
|
<p>Due to these differences, <strong>contributing a new provider to the OpenIddict stack is quite different from adding an aspnet-contrib provider</strong>:</p>
|
|
|
|
|
<h2 id="add-a-new-provider-node-for-the-new-provider">Add a new <code><Provider></code> node for the new provider</h2>
|
|
|
|
|
<p>To add a new OpenIddict web provider, <strong>the first step is to add a new <code><Provider></code> node</strong> to the <a href="https://github.com/openiddict/openiddict-core/blob/dev/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml">OpenIddictClientWebIntegrationProviders.xml</a> file. For instance:</p>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Zendesk" Documentation="https://developer.zendesk.com/documentation/live-chat/getting-started/auth/">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Zendesk" Id="89fdfe22-c796-4227-a44a-d9cd3c467bbb"
|
|
|
|
|
Documentation="https://developer.zendesk.com/documentation/live-chat/getting-started/auth/">
|
|
|
|
|
</Provider>
|
|
|
|
|
</code></pre><p>If available, a link to the official documentation MUST be added. If multiple languages are available, the following order SHOULD be used:</p>
|
|
|
|
|
<ul>
|
|
|
|
@@ -132,7 +133,7 @@ the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn't s
|
|
|
|
|
<ul>
|
|
|
|
|
<li>If the provider supports multiple environments, multiple <code><Environment></code> nodes - one per environment - MUST be added under <code><Provider></code>:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Salesforce">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Salesforce" Id="ce5bc4bc-6133-4e87-85ad-626b3c0a4427">
|
|
|
|
|
<Environment Name="Production" />
|
|
|
|
|
|
|
|
|
|
<Environment Name="Development" />
|
|
|
|
@@ -142,7 +143,7 @@ the approach used by the ASP.NET Core OAuth 2.0 base handler, that doesn't s
|
|
|
|
|
<ul>
|
|
|
|
|
<li>If the provider doesn't support multiple environment, a single <code><Environment></code> MUST be added (the <code>Name</code> attribute SHOULD be omitted):</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Google">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Google" Id="e0e90ce7-adb5-4b05-9f54-594941e5d960">
|
|
|
|
|
<Environment />
|
|
|
|
|
</Provider>
|
|
|
|
|
</code></pre><h2 id="add-the-appropriate-configuration-for-each-environment">Add the appropriate configuration for each environment</h2>
|
|
|
|
@@ -156,7 +157,7 @@ supports OpenID Connect/OAuth 2.0 server metadata.</p>
|
|
|
|
|
without the <code>/.well-known/openid-configuration</code> part. For instance, Google exposes its discovery document at <code>https://accounts.google.com/.well-known/openid-configuration</code>
|
|
|
|
|
so the correct issuer to use is <code>https://accounts.google.com/</code>:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Google">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Google" Id="e0e90ce7-adb5-4b05-9f54-594941e5d960">
|
|
|
|
|
<Environment Issuer="https://accounts.google.com/" />
|
|
|
|
|
</Provider>
|
|
|
|
|
</code></pre><ul>
|
|
|
|
@@ -164,7 +165,7 @@ so the correct issuer to use is <code>https://accounts.google.com/</code>:</li>
|
|
|
|
|
the value given in the documentation or the base address of the server) <strong>and</strong> a <code><Configuration></code> node with the static configuration needed by
|
|
|
|
|
the OpenIddict client to communicate with the remote authorization server. For instance:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Reddit">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Reddit" Id="01ae8033-935c-43b9-8568-eaf4d08c0613">
|
|
|
|
|
<Environment Issuer="https://www.reddit.com/">
|
|
|
|
|
<Configuration AuthorizationEndpoint="https://www.reddit.com/api/v1/authorize"
|
|
|
|
|
TokenEndpoint="https://www.reddit.com/api/v1/access_token"
|
|
|
|
@@ -177,7 +178,7 @@ the OpenIddict client to communicate with the remote authorization server. For i
|
|
|
|
|
</code></pre><div class="NOTE"><h5>Note</h5><p>If the provider doesn't support <code>grant_type=refresh_token</code> and only supports the authorization code flow
|
|
|
|
|
(typically with non-expiring access tokens), the <code><GrantType></code> nodes MUST be removed for clarity,
|
|
|
|
|
as the authorization code flow is always considered supported by default if no <code><GrantType></code> is present:</p>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Reddit">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Reddit" Id="01ae8033-935c-43b9-8568-eaf4d08c0613">
|
|
|
|
|
<Environment Issuer="https://www.reddit.com/">
|
|
|
|
|
<Configuration AuthorizationEndpoint="https://www.reddit.com/api/v1/authorize"
|
|
|
|
|
TokenEndpoint="https://www.reddit.com/api/v1/access_token"
|
|
|
|
@@ -187,7 +188,7 @@ as the authorization code flow is always considered supported by default if no <
|
|
|
|
|
</code></pre></div>
|
|
|
|
|
<div class="CAUTION"><h5>Caution</h5><p>If the provider doesn't support server metadata but is known to support Proof Key for Code Exchange (PKCE), a <code><CodeChallengeMethod></code> node MUST
|
|
|
|
|
be added under <code><Configuration></code> to ensure the OpenIddict client will send appropriate <code>code_challenge</code>/<code>code_challenge_method</code> parameters:</p>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Fitbit">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Fitbit" Id="10a558b9-8c81-47cc-8941-e54d0432fd51">
|
|
|
|
|
<Environment Issuer="https://www.fitbit.com/">
|
|
|
|
|
<Configuration AuthorizationEndpoint="https://www.fitbit.com/oauth2/authorize"
|
|
|
|
|
TokenEndpoint="https://api.fitbit.com/oauth2/token"
|
|
|
|
@@ -200,7 +201,7 @@ be added under <code><Configuration></code> to ensure the OpenIddict clien
|
|
|
|
|
<div class="NOTE"><h5>Note</h5><p>Some providers use a multitenant configuration that relies on a subdomain, a custom domain or a virtual path to discriminate tenant instances.
|
|
|
|
|
If the provider you want to support requires adding a dynamic part in one of its URIs, a <code><Setting></code> node MUST be added under <code><Provider></code> to
|
|
|
|
|
store the tenant name. Once added, the URIs can include a placeholder of the same name:</p>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Zendesk">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Zendesk" Id="89fdfe22-c796-4227-a44a-d9cd3c467bbb">
|
|
|
|
|
<!--
|
|
|
|
|
Note: Zendesk is a multitenant provider that relies on subdomains to identify instances.
|
|
|
|
|
As such, the following URIs all include a {tenant} placeholder that will be dynamically
|
|
|
|
@@ -219,14 +220,14 @@ store the tenant name. Once added, the URIs can include a placeholder of the sam
|
|
|
|
|
</code></pre></div>
|
|
|
|
|
<h2 id="test-the-generated-provider">Test the generated provider</h2>
|
|
|
|
|
<p>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 the new provider to the <code>OpenIddict.Sandbox.AspNetCore.Client</code> sandbox:</p>
|
|
|
|
|
To confirm it, build the solution and add an instance of the new provider to the <code>OpenIddict.Sandbox.AspNetCore.Client</code> sandbox:</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>Update <code>Startup.cs</code> to register your new provider:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-csharp">// Register the Web providers integrations.
|
|
|
|
|
options.UseWebProviders()
|
|
|
|
|
// ... other providers...
|
|
|
|
|
.Use[provider name](options =>
|
|
|
|
|
.Add[provider name](options =>
|
|
|
|
|
{
|
|
|
|
|
options.SetClientId("bXgwc0U3N3A3YWNuaWVsdlRmRWE6MTpjaQ");
|
|
|
|
|
options.SetClientSecret("VcohOgBp-6yQCurngo4GAyKeZh0D6SUCCSjJgEo1uRzJarjIUS");
|
|
|
|
@@ -259,7 +260,7 @@ made to the sandbox project don't need to be committed and included in your
|
|
|
|
|
Providers that implement OpenID Connect discovery or OAuth 2.0 authorization server metadata will typically return the client authentication methods they support.
|
|
|
|
|
If the provider doesn't expose its metadata, the supported methods MUST be added manually to the static configuration using one or multiple <code><TokenEndpointAuthMethod></code>:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Twitter">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Twitter" Id="1fd20ab5-d3f2-40aa-8c91-094f71652c65">
|
|
|
|
|
<Environment Issuer="https://twitter.com/">
|
|
|
|
|
<Configuration AuthorizationEndpoint="https://twitter.com/i/oauth2/authorize"
|
|
|
|
|
TokenEndpoint="https://api.twitter.com/2/oauth2/token"
|
|
|
|
@@ -273,7 +274,7 @@ If the provider doesn't expose its metadata, the supported methods MUST be a
|
|
|
|
|
</code></pre><ul>
|
|
|
|
|
<li>The provider MAY require sending one or multiple default or required scopes. If so, the default/required scopes MUST be added to the <code><Environment></code> node:</li>
|
|
|
|
|
</ul>
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Twitter" Documentation="https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code">
|
|
|
|
|
<pre><code class="lang-xml"><Provider Name="Twitter" Id="1fd20ab5-d3f2-40aa-8c91-094f71652c65">
|
|
|
|
|
<Environment Issuer="https://twitter.com/">
|
|
|
|
|
<Configuration AuthorizationEndpoint="https://twitter.com/i/oauth2/authorize"
|
|
|
|
|
TokenEndpoint="https://api.twitter.com/2/oauth2/token"
|
|
|
|
@@ -324,11 +325,11 @@ public class FormatNonStandardScopeParameter : IOpenIddictClientHandler<Proce
|
|
|
|
|
throw new ArgumentNullException(nameof(context));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
context.Request.Scope = context.Registration.ProviderName switch
|
|
|
|
|
context.Request.Scope = context.Registration.ProviderType switch
|
|
|
|
|
{
|
|
|
|
|
// The following providers are known to use comma-separated scopes instead of
|
|
|
|
|
// the standard format (that requires using a space as the scope separator):
|
|
|
|
|
Providers.Reddit => string.Join(",", context.Scopes),
|
|
|
|
|
ProviderTypes.Reddit => string.Join(",", context.Scopes),
|
|
|
|
|
|
|
|
|
|
_ => context.Request.Scope
|
|
|
|
|
};
|
|
|
|
|