From 6ed9eb25e1d9384a208e4989baf07e8a113bf1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 22 Dec 2022 14:56:50 +0100 Subject: [PATCH] Infer the redirection/post-logout redirection endpoint URIs from the redirect_uri/post_logout_redirect_uri configured in client registrations --- ...OpenIddictClientWebIntegrationGenerator.cs | 24 +++++++++++++++++++ .../Startup.cs | 20 ++++------------ .../Startup.cs | 23 +++++++----------- .../Startup.cs | 21 ++++------------ .../Startup.cs | 23 +++++++----------- .../OpenIddictClientConfiguration.cs | 18 ++++++++++++++ .../OpenIddictClientRegistration.cs | 8 +++++++ 7 files changed, 78 insertions(+), 59 deletions(-) diff --git a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs b/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs index 346105b4..c9bbfd62 100644 --- a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs +++ b/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs @@ -180,6 +180,10 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder /// /// Sets the post-logout redirection URI, if applicable. /// + /// + /// Note: the post-logout redirection URI is automatically added to + /// . + /// /// The post-logout redirection URI. /// The instance. public {{ provider.name }} SetPostLogoutRedirectUri(Uri uri) @@ -195,6 +199,10 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder /// /// Sets the post-logout redirection URI, if applicable. /// + /// + /// Note: the post-logout redirection URI is automatically added to + /// . + /// /// The post-logout redirection URI. /// The instance. public {{ provider.name }} SetPostLogoutRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri) @@ -210,6 +218,10 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder /// /// Sets the redirection URI, if applicable. /// + /// + /// Note: the redirection URI is automatically added to + /// . + /// /// The redirection URI. /// The instance. public {{ provider.name }} SetRedirectUri(Uri uri) @@ -225,6 +237,10 @@ public sealed partial class OpenIddictClientWebIntegrationBuilder /// /// Sets the redirection URI, if applicable. /// + /// + /// Note: the redirection URI is automatically added to + /// . + /// /// The redirection URI. /// The instance. public {{ provider.name }} SetRedirectUri([StringSyntax(StringSyntaxAttribute.Uri)] string uri) @@ -1092,11 +1108,19 @@ public sealed partial class OpenIddictClientWebIntegrationOptions /// /// Gets or sets the post-logout redirect URI. /// + /// + /// Note: this value is automatically added to + /// . + /// public Uri? PostLogoutRedirectUri { get; set; } /// /// Gets or sets the redirect URI. /// + /// + /// Note: this value is automatically added to + /// . + /// public Uri? RedirectUri { get; set; } /// diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs index f7ab0807..79061199 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Startup.cs @@ -40,21 +40,6 @@ namespace OpenIddict.Sandbox.AspNet.Client // Register the OpenIddict client components. .AddClient(options => { - // Enable the redirection endpoint needed to handle the callback stage. - // - // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint - // URI per provider, unless all the registered providers support returning a special "iss" - // parameter containing their URL as part of authorization responses. For more information, - // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. - options.SetRedirectionEndpointUris( - "callback/login/local", - "callback/login/github", - "callback/login/google", - "callback/login/twitter"); - - // Enable the post-logout redirection endpoint needed to handle the callback stage. - options.SetPostLogoutRedirectionEndpointUris("callback/logout/local"); - // Note: this sample uses the authorization code and refresh token // flows, but you can enable the other flows if necessary. options.AllowAuthorizationCodeFlow() @@ -92,6 +77,11 @@ namespace OpenIddict.Sandbox.AspNet.Client }); // Register the Web providers integrations. + // + // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint + // URI per provider, unless all the registered providers support returning a special "iss" + // parameter containing their URL as part of authorization responses. For more information, + // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. options.UseWebProviders() .UseGitHub(options => { diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs index fcc07683..0a0b08cc 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Startup.cs @@ -45,14 +45,6 @@ namespace OpenIddict.Sandbox.AspNet.Server // Register the OpenIddict client components. .AddClient(options => { - // Enable the redirection endpoint needed to handle the callback stage. - // - // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint - // URI per provider, unless all the registered providers support returning a special "iss" - // parameter containing their URL as part of authorization responses. For more information, - // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. - options.SetRedirectionEndpointUris("callback/login/github"); - // Note: this sample uses the code flow, but you can enable the other flows if necessary. options.AllowAuthorizationCodeFlow(); @@ -73,13 +65,16 @@ namespace OpenIddict.Sandbox.AspNet.Server .SetProductInformation(typeof(Startup).Assembly); // Register the Web providers integrations. + // + // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint + // URI per provider, unless all the registered providers support returning a special "iss" + // parameter containing their URL as part of authorization responses. For more information, + // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. options.UseWebProviders() - .UseGitHub(options => - { - options.SetClientId("c4ade52327b01ddacff3") - .SetClientSecret("da6bed851b75e317bf6b2cb67013679d9467c122") - .SetRedirectUri("callback/login/github"); - }); + .UseGitHub() + .SetClientId("c4ade52327b01ddacff3") + .SetClientSecret("da6bed851b75e317bf6b2cb67013679d9467c122") + .SetRedirectUri("callback/login/github"); }) // Register the OpenIddict server components. diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs index 408aa5ac..69b8d9ad 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Startup.cs @@ -74,22 +74,6 @@ public class Startup // Register the OpenIddict client components. .AddClient(options => { - // Enable the redirection endpoint needed to handle the callback stage. - // - // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint - // URI per provider, unless all the registered providers support returning a special "iss" - // parameter containing their URL as part of authorization responses. For more information, - // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. - options.SetRedirectionEndpointUris( - "callback/login/local", - "callback/login/github", - "callback/login/google", - "callback/login/reddit", - "callback/login/twitter"); - - // Enable the post-logout redirection endpoint needed to handle the callback stage. - options.SetPostLogoutRedirectionEndpointUris("callback/logout/local"); - // Note: this sample uses the authorization code and refresh token // flows, but you can enable the other flows if necessary. options.AllowAuthorizationCodeFlow() @@ -127,6 +111,11 @@ public class Startup }); // Register the Web providers integrations. + // + // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint + // URI per provider, unless all the registered providers support returning a special "iss" + // parameter containing their URL as part of authorization responses. For more information, + // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. options.UseWebProviders() .UseGitHub(options => { diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs index 77a750bf..3d678bc3 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Startup.cs @@ -68,14 +68,6 @@ public class Startup // Register the OpenIddict client components. .AddClient(options => { - // Enable the redirection endpoint needed to handle the callback stage. - // - // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint - // URI per provider, unless all the registered providers support returning a special "iss" - // parameter containing their URL as part of authorization responses. For more information, - // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. - options.SetRedirectionEndpointUris("callback/login/github"); - // Note: this sample uses the code flow, but you can enable the other flows if necessary. options.AllowAuthorizationCodeFlow(); @@ -96,13 +88,16 @@ public class Startup .SetProductInformation(typeof(Startup).Assembly); // Register the Web providers integrations. + // + // Note: to mitigate mix-up attacks, it's recommended to use a unique redirection endpoint + // URI per provider, unless all the registered providers support returning a special "iss" + // parameter containing their URL as part of authorization responses. For more information, + // see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.4. options.UseWebProviders() - .UseGitHub(options => - { - options.SetClientId("c4ade52327b01ddacff3") - .SetClientSecret("da6bed851b75e317bf6b2cb67013679d9467c122") - .SetRedirectUri("callback/login/github"); - }); + .UseGitHub() + .SetClientId("c4ade52327b01ddacff3") + .SetClientSecret("da6bed851b75e317bf6b2cb67013679d9467c122") + .SetRedirectUri("callback/login/github"); }) // Register the OpenIddict server components. diff --git a/src/OpenIddict.Client/OpenIddictClientConfiguration.cs b/src/OpenIddict.Client/OpenIddictClientConfiguration.cs index bdb34c68..92720ead 100644 --- a/src/OpenIddict.Client/OpenIddictClientConfiguration.cs +++ b/src/OpenIddict.Client/OpenIddictClientConfiguration.cs @@ -83,6 +83,24 @@ public sealed class OpenIddictClientConfiguration : IPostConfigureOptions registration.RedirectUri is not null) + .Select(registration => registration.RedirectUri!) + .Where(uri => !options.RedirectionEndpointUris.Contains(uri)) + .Distinct() + .ToList()); + + // Implicitly add the post_logout_redirect_uri attached to the client registrations + // to the list of post-logout redirection endpoints URIs if they haven't been added. + options.PostLogoutRedirectionEndpointUris.AddRange(options.Registrations + .Where(registration => registration.PostLogoutRedirectUri is not null) + .Select(registration => registration.PostLogoutRedirectUri!) + .Where(uri => !options.PostLogoutRedirectionEndpointUris.Contains(uri)) + .Distinct() + .ToList()); + // Ensure at least one flow has been enabled. if (options.GrantTypes.Count is 0 && options.ResponseTypes.Count is 0) { diff --git a/src/OpenIddict.Client/OpenIddictClientRegistration.cs b/src/OpenIddict.Client/OpenIddictClientRegistration.cs index 43f301f9..c018806a 100644 --- a/src/OpenIddict.Client/OpenIddictClientRegistration.cs +++ b/src/OpenIddict.Client/OpenIddictClientRegistration.cs @@ -29,11 +29,19 @@ public sealed class OpenIddictClientRegistration /// /// Gets or sets the URI of the redirection endpoint that will handle the callback. /// + /// + /// Note: this value is automatically added to + /// . + /// public Uri? RedirectUri { get; set; } /// /// Gets or sets the URI of the post-logout redirection endpoint that will handle the callback. /// + /// + /// Note: this value is automatically added to + /// . + /// public Uri? PostLogoutRedirectUri { get; set; } ///