Browse Source

Add Atlassian to the list of supported providers

pull/2029/head
Kévin Chalet 2 years ago
parent
commit
a098a8e10d
  1. 42
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs
  2. 15
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs
  3. 67
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

42
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs

@ -114,6 +114,13 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.Configuration.GrantTypesSupported.Add(GrantTypes.RefreshToken);
}
else if (context.Registration.ProviderType is ProviderTypes.Atlassian)
{
context.Configuration.GrantTypesSupported.Add(GrantTypes.AuthorizationCode);
context.Configuration.GrantTypesSupported.Add(GrantTypes.Implicit);
context.Configuration.GrantTypesSupported.Add(GrantTypes.RefreshToken);
}
else if (context.Registration.ProviderType is ProviderTypes.Auth0)
{
context.Configuration.GrantTypesSupported.Add(GrantTypes.AuthorizationCode);
@ -214,16 +221,25 @@ public static partial class OpenIddictClientWebIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
// While it is a recommended node, some providers don't include "scopes_supported" in their
// configuration and thus are treated as OAuth 2.0-only providers by the OpenIddict client.
// To avoid that, the "openid" scope is manually added to indicate OpenID Connect is supported.
// Atlassian includes the "openid" scope in its server configuration but doesn't currently allow
// requesting it. To prevent an error from being returned, OpenID Connect support is disabled.
if (context.Registration.ProviderType is ProviderTypes.Atlassian)
{
context.Configuration.ScopesSupported.Remove(Scopes.OpenId);
}
if (context.Registration.ProviderType is ProviderTypes.DocuSign)
// DocuSign supports OpenID Connect but doesn't format the "openid" scope using the standard casing.
// To ensure DocuSign is not treated as an OAuth 2.0-only provider, the invalid "OpenId" scope is
// removed from the list and the "openid" value is added to indicate OpenID Connect is supported.
else if (context.Registration.ProviderType is ProviderTypes.DocuSign)
{
context.Configuration.ScopesSupported.Remove("OpenId");
context.Configuration.ScopesSupported.Add(Scopes.OpenId);
}
// While it is a recommended node, these providers don't include "scopes_supported" in their
// configuration and thus are treated as OAuth 2.0-only providers by the OpenIddict client.
// To avoid that, the "openid" scope is manually added to indicate OpenID Connect is supported.
else if (context.Registration.ProviderType is ProviderTypes.EpicGames or ProviderTypes.Xero)
{
context.Configuration.ScopesSupported.Add(Scopes.OpenId);
@ -317,6 +333,14 @@ public static partial class OpenIddictClientWebIntegrationHandlers
ClientAuthenticationMethods.PrivateKeyJwt);
}
// Atlassian doesn't return a "revocation_endpoint_auth_methods_supported" node in its
// server configuration but only supports the "client_secret_post" authentication method.
else if (context.Registration.ProviderType is ProviderTypes.Atlassian)
{
context.Configuration.RevocationEndpointAuthMethodsSupported.Add(
ClientAuthenticationMethods.ClientSecretPost);
}
// Google doesn't properly implement the device authorization grant, doesn't support
// basic client authentication for the device authorization endpoint and returns
// a generic "invalid_request" error when using "client_secret_basic" instead of
@ -366,10 +390,18 @@ public static partial class OpenIddictClientWebIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
// While Atlassian implements an OpenID Connect userinfo endpoint, using it requires
// requesting the "openid" scope, which isn't allowed yet. To work around this
// limitation, the userinfo endpoint is replaced by the generic /me endpoint URI.
if (context.Registration.ProviderType is ProviderTypes.Atlassian)
{
context.Configuration.UserinfoEndpoint = new Uri("https://api.atlassian.com/me", UriKind.Absolute);
}
// While Auth0 exposes an OpenID Connect-compliant logout endpoint, its address is not returned
// as part of the configuration document. To ensure RP-initiated logout is supported with Auth0,
// "end_session_endpoint" is manually computed using the issuer URI and added to the configuration.
if (context.Registration.ProviderType is ProviderTypes.Auth0)
else if (context.Registration.ProviderType is ProviderTypes.Auth0)
{
context.Configuration.EndSessionEndpoint ??= OpenIddictHelpers.CreateAbsoluteUri(
context.Registration.Issuer, "oidc/logout");

15
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs

@ -1241,6 +1241,9 @@ public static partial class OpenIddictClientWebIntegrationHandlers
ProviderTypes.ArcGisOnline or ProviderTypes.Trakt
=> (string?) context.UserinfoResponse?["username"],
// Atlassian returns the user identifier as a custom "account_id" node:
ProviderTypes.Atlassian => (string?) context.UserinfoResponse?["account_id"],
// These providers return the user identifier as a custom "id" node:
ProviderTypes.Basecamp or ProviderTypes.Box or ProviderTypes.Dailymotion or
ProviderTypes.Deezer or ProviderTypes.Discord or ProviderTypes.Disqus or
@ -1578,6 +1581,18 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.Request["resource"] = settings.Resource;
}
// Atlassian requires sending an "audience" parameter (by default, "api.atlassian.com").
//
// The documentation also indicates the "prompt" parameter is required, but no error is
// returned if this parameter is not explicitly included in the authorization request.
else if (context.Registration.ProviderType is ProviderTypes.Atlassian)
{
var settings = context.Registration.GetAtlassianSettings();
context.Request.Audiences = [settings.Audience];
context.Request.Prompt = settings.Prompt;
}
// By default, Google doesn't return a refresh token but allows sending an "access_type"
// parameter to retrieve one (but it is only returned during the first authorization dance).
else if (context.Registration.ProviderType is ProviderTypes.Google)

67
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml

@ -80,6 +80,27 @@
<Property Name="UserCode" DictionaryKey=".user_code" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀██ ▄▄ ██ ▄▄ ██ █████ ▄▄▄██
█ ▀▀ ██ ▀▀ ██ ▀▀ ██ █████ ▄▄▄██
█ ██ ██ █████ █████ ▀▀ ██ ▀▀▀██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->
<Provider Name="Apple" DisplayName="Sign in with Apple" Id="f59a420e-9d00-4a85-94a3-8ecacc5968d8"
Documentation="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api">
<Environment Issuer="https://appleid.apple.com/" />
<Setting PropertyName="SigningKey" ParameterName="key" Type="SigningKey" Required="true"
Description="The Elliptic Curve Digital Signature Algorithm (ECDSA) signing key associated with the developer account">
<SigningAlgorithm Value="ES256" />
</Setting>
<Setting PropertyName="TeamId" ParameterName="identifier" Type="String" Required="true"
Description="The team ID associated with the developer account" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀██ ▄▄▀██ ▄▄▀██ ▄▄ █▄ ▄██ ▄▄▄ ████ ▄▄▄ ██ ▀██ ██ ████▄ ▄██ ▀██ ██ ▄▄▄██
@ -104,27 +125,6 @@
</Environment>
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀██ ▄▄ ██ ▄▄ ██ █████ ▄▄▄██
█ ▀▀ ██ ▀▀ ██ ▀▀ ██ █████ ▄▄▄██
█ ██ ██ █████ █████ ▀▀ ██ ▀▀▀██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->
<Provider Name="Apple" DisplayName="Sign in with Apple" Id="f59a420e-9d00-4a85-94a3-8ecacc5968d8"
Documentation="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api">
<Environment Issuer="https://appleid.apple.com/" />
<Setting PropertyName="SigningKey" ParameterName="key" Type="SigningKey" Required="true"
Description="The Elliptic Curve Digital Signature Algorithm (ECDSA) signing key associated with the developer account">
<SigningAlgorithm Value="ES256" />
</Setting>
<Setting PropertyName="TeamId" ParameterName="identifier" Type="String" Required="true"
Description="The team ID associated with the developer account" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀██ ▄▄▄ █ ▄▄▀██ ▀██ █ ▄▄▀██
@ -138,6 +138,31 @@
<Environment Issuer="https://app.asana.com/api/1.0" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀█▄▄ ▄▄██ ████ ▄▄▀██ ▄▄▄ ██ ▄▄▄ █▄ ▄█ ▄▄▀██ ▀██ ██
█ ▀▀ ███ ████ ████ ▀▀ ██▄▄▄▀▀██▄▄▄▀▀██ ██ ▀▀ ██ █ █ ██
█ ██ ███ ████ ▀▀ █ ██ ██ ▀▀▀ ██ ▀▀▀ █▀ ▀█ ██ ██ ██▄ ██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->
<Provider Name="Atlassian" Id="e529316b-cbda-4bbd-8bac-9787457cdaaa"
Documentation="https://developer.atlassian.com/cloud/jira/platform/oauth-2-3lo-apps/">
<Environment Issuer="https://auth.atlassian.com/">
<!--
Note: Atlassian requires sending the "read:me" scope to be able to use the userinfo endpoint.
-->
<Scope Name="read:me" Default="true" Required="true" />
</Environment>
<Setting PropertyName="Audience" ParameterName="audience" Type="String" Required="true" DefaultValue="api.atlassian.com"
Description="The value used as the 'audience' parameter (by default, 'api.atlassian.com')" />
<Setting PropertyName="Prompt" ParameterName="prompt" Type="String" Required="true" DefaultValue="consent"
Description="The value used as the 'prompt' parameter (by default, 'consent')" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
█ ▄▄▀██ ██ █▄▄ ▄▄██ ██ █ ▄▄ ██

Loading…
Cancel
Save