From 13d88ca84b6618c643abb84cdc763fd9e4731108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Fri, 17 Mar 2023 13:42:25 +0100 Subject: [PATCH] Add Epic Games to the list of supported providers --- ...OpenIddictClientWebIntegrationGenerator.cs | 4 +-- ...ictClientSystemNetHttpHandlers.Exchange.cs | 3 +- ...tClientWebIntegrationHandlers.Discovery.cs | 9 +++-- ...ctClientWebIntegrationHandlers.Exchange.cs | 35 +++++++++++++------ ...penIddictClientWebIntegrationProviders.xml | 13 +++++++ ...tionSystemNetHttpHandlers.Introspection.cs | 3 +- 6 files changed, 48 insertions(+), 19 deletions(-) diff --git a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs b/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs index 8b02c66d..56e96938 100644 --- a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs +++ b/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 the documentation. - /// {{~ end ~}} + /// /// This extension can be safely called multiple times. /// The instance. 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 the documentation. - /// {{~ end ~}} + /// /// This extension can be safely called multiple times. /// The delegate used to configure the OpenIddict/{{ provider.display_name }} options. /// The instance. diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs index a000101d..e4740290 100644 --- a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.Exchange.cs +++ b/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)) { diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs index cdeaf2ca..f3980929 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Discovery.cs +++ b/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); } diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs index d85a3464..5da911b1 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs @@ -49,7 +49,7 @@ public static partial class OpenIddictClientWebIntegrationHandlers = OpenIddictClientHandlerDescriptor.CreateBuilder() .AddFilter() .UseSingletonHandler() - .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; diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml index 831335d6..94755cb5 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml @@ -238,6 +238,19 @@ + + + + + +