From fa1f23469f2fecfa82fa38147f601d969bd9aaa4 Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Sun, 6 Mar 2022 15:10:03 +0100 Subject: [PATCH] feat(oidc): customizable base redirect uri Closes https://github.com/ory-corp/cloud/issues/2003 --- driver/config/config.go | 5 +++++ embedx/config.schema.json | 9 +++++++++ selfservice/strategy/oidc/provider_auth0.go | 2 +- selfservice/strategy/oidc/provider_discord.go | 2 +- .../strategy/oidc/provider_generic_oidc.go | 2 +- .../strategy/oidc/provider_generic_test.go | 18 ++++++++++++++++++ selfservice/strategy/oidc/provider_github.go | 2 +- .../strategy/oidc/provider_github_app.go | 2 +- selfservice/strategy/oidc/provider_gitlab.go | 2 +- selfservice/strategy/oidc/provider_slack.go | 2 +- selfservice/strategy/oidc/provider_spotify.go | 4 ++-- selfservice/strategy/oidc/provider_vk.go | 2 +- selfservice/strategy/oidc/provider_yandex.go | 2 +- 13 files changed, 43 insertions(+), 11 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index 3afcafebfab9..bb9ee710cba4 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -158,6 +158,7 @@ const ( ViperKeyPasswordIdentifierSimilarityCheckEnabled = "selfservice.methods.password.config.identifier_similarity_check_enabled" ViperKeyIgnoreNetworkErrors = "selfservice.methods.password.config.ignore_network_errors" ViperKeyTOTPIssuer = "selfservice.methods.totp.config.issuer" + ViperKeyOIDCBaseRedirectURL = "selfservice.methods.oidc.config.base_redirect_uri" ViperKeyWebAuthnRPDisplayName = "selfservice.methods.webauthn.config.rp.display_name" ViperKeyWebAuthnRPID = "selfservice.methods.webauthn.config.rp.id" ViperKeyWebAuthnRPOrigin = "selfservice.methods.webauthn.config.rp.origin" @@ -506,6 +507,10 @@ func (p *Config) TOTPIssuer() string { return p.Source().StringF(ViperKeyTOTPIssuer, p.SelfPublicURL().Hostname()) } +func (p *Config) OIDCRedirectURIBase() *url.URL { + return p.Source().URIF(ViperKeyOIDCBaseRedirectURL, p.SelfPublicURL()) +} + func (p *Config) IdentityTraitsSchemas() (Schemas, error) { var ss Schemas out, err := p.p.Marshal(kjson.Parser()) diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 710528152147..a9b119148b60 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -1382,6 +1382,15 @@ "type": "object", "additionalProperties": false, "properties": { + "base_redirect_uri": { + "type": "string", + "title": "Base URL for OAuth2 Redirect URIs", + "description": "Can be used to modify the base URL for OAuth2 Redirect URLs. If unset, the Public Base URL will be used.", + "format": "uri", + "examples": [ + "https://auth.myexample.org/" + ] + }, "providers": { "title": "OpenID Connect and OAuth2 Providers", "description": "A list and configuration of OAuth2 and OpenID Connect providers Ory Kratos should integrate with.", diff --git a/selfservice/strategy/oidc/provider_auth0.go b/selfservice/strategy/oidc/provider_auth0.go index 158429fda2ce..e930f9627f0c 100644 --- a/selfservice/strategy/oidc/provider_auth0.go +++ b/selfservice/strategy/oidc/provider_auth0.go @@ -56,7 +56,7 @@ func (g *ProviderAuth0) oauth2(ctx context.Context) (*oauth2.Config, error) { TokenURL: tokenUrl.String(), }, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } return c, nil diff --git a/selfservice/strategy/oidc/provider_discord.go b/selfservice/strategy/oidc/provider_discord.go index b98d2c827099..4fe18e87b215 100644 --- a/selfservice/strategy/oidc/provider_discord.go +++ b/selfservice/strategy/oidc/provider_discord.go @@ -42,7 +42,7 @@ func (d *ProviderDiscord) oauth2(ctx context.Context) *oauth2.Config { AuthURL: discordgo.EndpointOauth2 + "authorize", TokenURL: discordgo.EndpointOauth2 + "token", }, - RedirectURL: d.config.Redir(d.reg.Config(ctx).SelfPublicURL()), + RedirectURL: d.config.Redir(d.reg.Config(ctx).OIDCRedirectURIBase()), Scopes: d.config.Scope, } } diff --git a/selfservice/strategy/oidc/provider_generic_oidc.go b/selfservice/strategy/oidc/provider_generic_oidc.go index d193fe2f44f9..371d89682cb6 100644 --- a/selfservice/strategy/oidc/provider_generic_oidc.go +++ b/selfservice/strategy/oidc/provider_generic_oidc.go @@ -56,7 +56,7 @@ func (g *ProviderGenericOIDC) oauth2ConfigFromEndpoint(ctx context.Context, endp ClientSecret: g.config.ClientSecret, Endpoint: endpoint, Scopes: scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } } diff --git a/selfservice/strategy/oidc/provider_generic_test.go b/selfservice/strategy/oidc/provider_generic_test.go index 2dcfe38255f4..5e200801bf8b 100644 --- a/selfservice/strategy/oidc/provider_generic_test.go +++ b/selfservice/strategy/oidc/provider_generic_test.go @@ -50,6 +50,24 @@ func makeAuthCodeURL(t *testing.T, r *login.Flow, reg *driver.RegistryDefault) s func TestProviderGenericOIDC_AddAuthCodeURLOptions(t *testing.T) { conf, reg := internal.NewFastRegistryWithMocks(t) conf.MustSet(config.ViperKeyPublicBaseURL, "https://ory.sh") + t.Run("case=redirectURI is public base url", func(t *testing.T) { + r := &login.Flow{ID: x.NewUUID(), Refresh: true} + actual, err := url.ParseRequestURI(makeAuthCodeURL(t, r, reg)) + require.NoError(t, err) + assert.Contains(t, actual.Query().Get("redirect_uri"), "https://ory.sh") + }) + + t.Run("case=redirectURI is public base url", func(t *testing.T) { + conf.MustSet(config.ViperKeyOIDCBaseRedirectURL, "https://example.org") + t.Cleanup(func() { + conf.MustSet(config.ViperKeyOIDCBaseRedirectURL, nil) + }) + r := &login.Flow{ID: x.NewUUID(), Refresh: true} + actual, err := url.ParseRequestURI(makeAuthCodeURL(t, r, reg)) + require.NoError(t, err) + assert.Contains(t, actual.Query().Get("redirect_uri"), "https://example.org") + }) + t.Run("case=expect prompt to be login with forced flag", func(t *testing.T) { r := &login.Flow{ ID: x.NewUUID(), diff --git a/selfservice/strategy/oidc/provider_github.go b/selfservice/strategy/oidc/provider_github.go index 01cf8fc5aaac..3efd08f98da3 100644 --- a/selfservice/strategy/oidc/provider_github.go +++ b/selfservice/strategy/oidc/provider_github.go @@ -43,7 +43,7 @@ func (g *ProviderGitHub) oauth2(ctx context.Context) *oauth2.Config { ClientSecret: g.config.ClientSecret, Endpoint: github.Endpoint, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } } diff --git a/selfservice/strategy/oidc/provider_github_app.go b/selfservice/strategy/oidc/provider_github_app.go index bc1e7571e630..3fd10b6917f7 100644 --- a/selfservice/strategy/oidc/provider_github_app.go +++ b/selfservice/strategy/oidc/provider_github_app.go @@ -40,7 +40,7 @@ func (g *ProviderGitHubApp) oauth2(ctx context.Context) *oauth2.Config { ClientSecret: g.config.ClientSecret, Endpoint: github.Endpoint, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } } diff --git a/selfservice/strategy/oidc/provider_gitlab.go b/selfservice/strategy/oidc/provider_gitlab.go index 76e5ed936543..803b8043f6b4 100644 --- a/selfservice/strategy/oidc/provider_gitlab.go +++ b/selfservice/strategy/oidc/provider_gitlab.go @@ -56,7 +56,7 @@ func (g *ProviderGitLab) oauth2(ctx context.Context) (*oauth2.Config, error) { TokenURL: tokenUrl.String(), }, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), }, nil } diff --git a/selfservice/strategy/oidc/provider_slack.go b/selfservice/strategy/oidc/provider_slack.go index 32c31209445e..c6e99f2edc5f 100644 --- a/selfservice/strategy/oidc/provider_slack.go +++ b/selfservice/strategy/oidc/provider_slack.go @@ -44,7 +44,7 @@ func (d *ProviderSlack) oauth2(ctx context.Context) *oauth2.Config { AuthURL: "https://slack.com/oauth/authorize", TokenURL: slack.APIURL + "oauth.access", }, - RedirectURL: d.config.Redir(d.reg.Config(ctx).SelfPublicURL()), + RedirectURL: d.config.Redir(d.reg.Config(ctx).OIDCRedirectURIBase()), Scopes: d.config.Scope, } } diff --git a/selfservice/strategy/oidc/provider_spotify.go b/selfservice/strategy/oidc/provider_spotify.go index 1a6ee9c84ec0..85c8b4749448 100644 --- a/selfservice/strategy/oidc/provider_spotify.go +++ b/selfservice/strategy/oidc/provider_spotify.go @@ -43,7 +43,7 @@ func (g *ProviderSpotify) oauth2(ctx context.Context) *oauth2.Config { ClientSecret: g.config.ClientSecret, Endpoint: spotify.Endpoint, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } } @@ -64,7 +64,7 @@ func (g *ProviderSpotify) Claims(ctx context.Context, exchange *oauth2.Token) (* } auth := spotifyauth.New( - spotifyauth.WithRedirectURL(g.config.Redir(g.reg.Config(ctx).SelfPublicURL())), + spotifyauth.WithRedirectURL(g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase())), spotifyauth.WithScopes(spotifyauth.ScopeUserReadPrivate)) client := spotifyapi.New(auth.Client(ctx, exchange)) diff --git a/selfservice/strategy/oidc/provider_vk.go b/selfservice/strategy/oidc/provider_vk.go index 768c0bf051ff..fd2b5f3ef9c4 100644 --- a/selfservice/strategy/oidc/provider_vk.go +++ b/selfservice/strategy/oidc/provider_vk.go @@ -43,7 +43,7 @@ func (g *ProviderVK) oauth2(ctx context.Context) *oauth2.Config { TokenURL: "https://oauth.vk.com/access_token", }, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } } diff --git a/selfservice/strategy/oidc/provider_yandex.go b/selfservice/strategy/oidc/provider_yandex.go index d6a219c516e8..1c627183bd87 100644 --- a/selfservice/strategy/oidc/provider_yandex.go +++ b/selfservice/strategy/oidc/provider_yandex.go @@ -41,7 +41,7 @@ func (g *ProviderYandex) oauth2(ctx context.Context) *oauth2.Config { TokenURL: "https://oauth.yandex.com/token", }, Scopes: g.config.Scope, - RedirectURL: g.config.Redir(g.reg.Config(ctx).SelfPublicURL()), + RedirectURL: g.config.Redir(g.reg.Config(ctx).OIDCRedirectURIBase()), } }