Browse Source

Add Epic Games to the list of supported providers

pull/1736/head
Kévin Chalet 4 years ago
parent
commit
13d88ca84b
  1. 4
      gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs
  2. 3
      src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs
  3. 9
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs
  4. 35
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs
  5. 13
      src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml
  6. 3
      src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs

4
gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs

@ -70,8 +70,8 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// Enables the {{ provider.display_name }} integration and registers the associated services in the DI container.
{{~ if provider.documentation ~}}
/// For more information, read <see href=""{{ provider.documentation }}"">the documentation</see>.
/// </summary>
{{~ end ~}}
/// </summary>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder.{{ provider.name }}""/> instance.</returns>
public OpenIddictClientWebIntegrationBuilder.{{ provider.name }} Use{{ provider.name }}()
@ -92,8 +92,8 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder
/// Enables the {{ provider.display_name }} integration and registers the associated services in the DI container.
{{~ if provider.documentation ~}}
/// For more information, read <see href=""{{ provider.documentation }}"">the documentation</see>.
/// </summary>
{{~ end ~}}
/// </summary>
/// <remarks>This extension can be safely called multiple times.</remarks>
/// <param name=""configuration"">The delegate used to configure the OpenIddict/{{ provider.display_name }} options.</param>
/// <returns>The <see cref=""OpenIddictClientWebIntegrationBuilder""/> instance.</returns>

3
src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs

@ -91,7 +91,8 @@ public static partial class OpenIddictClientSystemNetHttpHandlers
//
// See https://tools.ietf.org/html/rfc8414#section-2
// and https://tools.ietf.org/html/rfc6749#section-2.3.1 for more information.
if (!string.IsNullOrEmpty(context.Request.ClientId) &&
if (request.Headers.Authorization is null &&
!string.IsNullOrEmpty(context.Request.ClientId) &&
!string.IsNullOrEmpty(context.Request.ClientSecret) &&
UseBasicAuthentication(context.Configuration))
{

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

@ -99,7 +99,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
context.Configuration.GrantTypesSupported.Add(GrantTypes.RefreshToken);
}
else if (context.Registration.ProviderName is Providers.Cognito or Providers.Microsoft)
else if (context.Registration.ProviderName is Providers.Cognito or Providers.EpicGames or Providers.Microsoft)
{
context.Configuration.GrantTypesSupported.Add(GrantTypes.AuthorizationCode);
context.Configuration.GrantTypesSupported.Add(GrantTypes.ClientCredentials);
@ -181,11 +181,10 @@ public static partial class OpenIddictClientWebIntegrationHandlers
throw new ArgumentNullException(nameof(context));
}
// While it is a recommended node, Xero doesn't include "scopes_supported" in its server
// configuration and thus is treated as an OAuth 2.0-only provider by the OpenIddict client.
//
// 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.
if (context.Registration.ProviderName is Providers.Xero)
if (context.Registration.ProviderName is Providers.EpicGames or Providers.Xero)
{
context.Configuration.ScopesSupported.Add(Scopes.OpenId);
}

35
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs

@ -49,7 +49,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers
= OpenIddictClientHandlerDescriptor.CreateBuilder<PrepareTokenRequestContext>()
.AddFilter<RequireHttpMetadataUri>()
.UseSingletonHandler<AttachNonStandardBasicAuthenticationCredentials>()
.SetOrder(AttachBasicAuthenticationCredentials.Descriptor.Order + 500)
.SetOrder(AttachBasicAuthenticationCredentials.Descriptor.Order - 500)
.SetType(OpenIddictClientHandlerType.BuiltIn)
.Build();
@ -75,25 +75,40 @@ public static partial class OpenIddictClientWebIntegrationHandlers
// These providers require using basic authentication to flow the client_id
// for all types of client applications, even when there's no client_secret.
//
// Note: only cases where the client secret is null are handled here (scenarios
// where the Authorization header includes a non-empty password are handled by
// a generic handler in the OpenIddict.Client.SystemNetHttp integration package).
if (context.Registration.ProviderName is Providers.Reddit &&
!string.IsNullOrEmpty(context.Request.ClientId) &&
string.IsNullOrEmpty(context.Request.ClientSecret))
!string.IsNullOrEmpty(context.Request.ClientId))
{
// Important: the client_id MUST be formURL-encoded before being base64-encoded.
// Important: the credentials MUST be formURL-encoded before being base64-encoded.
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(new StringBuilder()
.Append(EscapeDataString(context.Request.ClientId))
.Append(':')
.Append(EscapeDataString(context.Request.ClientSecret))
.ToString()));
// Attach the authorization header containing the client identifier to the HTTP request.
request.Headers.Authorization = new AuthenticationHeaderValue(Schemes.Basic, credentials);
// Remove the client identifier from the request payload to ensure it's not sent twice.
context.Request.ClientId = null;
// Remove the client credentials from the request payload to ensure they are not sent twice.
context.Request.ClientId = context.Request.ClientSecret = null;
}
// These providers don't implement the standard version of the client_secret_basic
// authentication method as they don't support formURL-encoding the client credentials.
else if (context.Registration.ProviderName is Providers.EpicGames &&
!string.IsNullOrEmpty(context.Request.ClientId) &&
!string.IsNullOrEmpty(context.Request.ClientSecret))
{
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(new StringBuilder()
.Append(context.Request.ClientId)
.Append(':')
.Append(context.Request.ClientSecret)
.ToString()));
// Attach the authorization header containing the client identifier to the HTTP request.
request.Headers.Authorization = new AuthenticationHeaderValue(Schemes.Basic, credentials);
// Remove the client credentials from the request payload to ensure they are not sent twice.
context.Request.ClientId = context.Request.ClientSecret = null;
}
return default;

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

@ -238,6 +238,19 @@
</Environment>
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██ ▄▄▄██ ▄▄ █▄ ▄██ ▄▄▀████ ▄▄ █ ▄▄▀██ ▄▀▄ ██ ▄▄▄██ ▄▄▄ ██
██ ▄▄▄██ ▀▀ ██ ███ ███████ █▀▀█ ▀▀ ██ █ █ ██ ▄▄▄██▄▄▄▀▀██
██ ▀▀▀██ ████▀ ▀██ ▀▀▄████ ▀▀▄█ ██ ██ ███ ██ ▀▀▀██ ▀▀▀ ██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
-->
<Provider Name="EpicGames" DisplayName="Epic Games"
Documentation="https://dev.epicgames.com/docs/web-api-ref/authentication">
<Environment Issuer="https://api.epicgames.dev/epic/oauth/v1" />
</Provider>
<!--
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██ ▄▄▄█▄ ▄█▄▄ ▄▄██ ▄▄▀█▄ ▄█▄▄ ▄▄██

3
src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.Introspection.cs

@ -91,7 +91,8 @@ public static partial class OpenIddictValidationSystemNetHttpHandlers
//
// See https://tools.ietf.org/html/rfc8414#section-2
// and https://tools.ietf.org/html/rfc6749#section-2.3.1 for more information.
if (!string.IsNullOrEmpty(context.Request.ClientId) &&
if (request.Headers.Authorization is null &&
!string.IsNullOrEmpty(context.Request.ClientId) &&
!string.IsNullOrEmpty(context.Request.ClientSecret) &&
UseBasicAuthentication(context.Configuration))
{

Loading…
Cancel
Save