From ebfb54da151f03a5013f96f2691a59f35d320877 Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Tue, 14 Jun 2022 11:22:13 +0200 Subject: [PATCH] fix: support issuer with and without trailing slash BREAKING CHANGE: The `iss` (issuer) value no longer appends a trailing slash but instead uses the raw value set in the config. Setting ```yaml urls: self: issuer: https://auth.example.com ``` has changed ```patch - "iss": "https://auth.example.com/" + "iss": "https://auth.example.com" ``` To set a trailing slash make sure to set it in the config value: ```yaml urls: self: issuer: https://auth.example.com/ ``` Closes #1482 --- driver/config/provider.go | 4 +--- driver/config/provider_test.go | 8 ++++---- .../TestHandlerWellKnown-hsm_enabled=false.json | 2 +- oauth2/handler.go | 11 +++++------ oauth2/introspector_test.go | 4 ++-- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/driver/config/provider.go b/driver/config/provider.go index 4e7703e4700..28865ec53c8 100644 --- a/driver/config/provider.go +++ b/driver/config/provider.go @@ -314,9 +314,7 @@ func (p *DefaultProvider) PublicURL(ctx context.Context) *url.URL { } func (p *DefaultProvider) IssuerURL(ctx context.Context) *url.URL { - issuerURL := p.getProvider(ctx).RequestURIF(KeyIssuerURL, p.fallbackURL(ctx, "/", p.host(PublicInterface), p.port(PublicInterface))) - issuerURL.Path = strings.TrimRight(issuerURL.Path, "/") + "/" - return urlRoot(issuerURL) + return p.getProvider(ctx).RequestURIF(KeyIssuerURL, p.fallbackURL(ctx, "/", p.host(PublicInterface), p.port(PublicInterface))) } func (p *DefaultProvider) OAuth2ClientRegistrationURL(ctx context.Context) *url.URL { diff --git a/driver/config/provider_test.go b/driver/config/provider_test.go index 3cb3bc90985..04a596d2408 100644 --- a/driver/config/provider_test.go +++ b/driver/config/provider_test.go @@ -153,7 +153,7 @@ func TestProviderIssuerURL(t *testing.T) { l.Logrus().SetOutput(ioutil.Discard) p := MustNew(context.Background(), l) p.MustSet(ctx, KeyIssuerURL, "http://hydra.localhost") - assert.Equal(t, "http://hydra.localhost/", p.IssuerURL(ctx).String()) + assert.Equal(t, "http://hydra.localhost", p.IssuerURL(ctx).String()) p2 := MustNew(context.Background(), l) p2.MustSet(ctx, KeyIssuerURL, "http://hydra.localhost/") @@ -168,7 +168,7 @@ func TestProviderIssuerPublicURL(t *testing.T) { p.MustSet(ctx, KeyIssuerURL, "http://hydra.localhost") p.MustSet(ctx, KeyPublicURL, "http://hydra.example") - assert.Equal(t, "http://hydra.localhost/", p.IssuerURL(ctx).String()) + assert.Equal(t, "http://hydra.localhost", p.IssuerURL(ctx).String()) assert.Equal(t, "http://hydra.example/", p.PublicURL(ctx).String()) assert.Equal(t, "http://hydra.localhost/.well-known/jwks.json", p.JWKSURL(ctx).String()) assert.Equal(t, "http://hydra.example/oauth2/fallbacks/consent", p.ConsentURL(ctx).String()) @@ -179,7 +179,7 @@ func TestProviderIssuerPublicURL(t *testing.T) { assert.Equal(t, "http://hydra.example/userinfo", p.OIDCDiscoveryUserinfoEndpoint(ctx).String()) p2 := MustNew(context.Background(), l) - p2.MustSet(ctx, KeyIssuerURL, "http://hydra.localhost") + p2.MustSet(ctx, KeyIssuerURL, "http://hydra.localhost/") assert.Equal(t, "http://hydra.localhost/", p2.IssuerURL(ctx).String()) assert.Equal(t, "http://hydra.localhost/", p2.PublicURL(ctx).String()) assert.Equal(t, "http://hydra.localhost/.well-known/jwks.json", p2.JWKSURL(ctx).String()) @@ -282,7 +282,7 @@ func TestViperProviderValidates(t *testing.T) { assert.Equal(t, []string{"whatever"}, c.DefaultClientScope(ctx)) // urls - assert.Equal(t, urlx.ParseOrPanic("https://issuer/"), c.IssuerURL(ctx)) + assert.Equal(t, urlx.ParseOrPanic("https://issuer"), c.IssuerURL(ctx)) assert.Equal(t, urlx.ParseOrPanic("https://public/"), c.PublicURL(ctx)) assert.Equal(t, urlx.ParseOrPanic("https://login/"), c.LoginURL(ctx)) assert.Equal(t, urlx.ParseOrPanic("https://consent/"), c.ConsentURL(ctx)) diff --git a/oauth2/.snapshots/TestHandlerWellKnown-hsm_enabled=false.json b/oauth2/.snapshots/TestHandlerWellKnown-hsm_enabled=false.json index 12ecce8a4f0..9d8f91fabae 100644 --- a/oauth2/.snapshots/TestHandlerWellKnown-hsm_enabled=false.json +++ b/oauth2/.snapshots/TestHandlerWellKnown-hsm_enabled=false.json @@ -1,5 +1,5 @@ { - "issuer": "http://hydra.localhost/", + "issuer": "http://hydra.localhost", "authorization_endpoint": "http://hydra.localhost/oauth2/auth", "registration_endpoint": "http://client-register/registration", "token_endpoint": "http://hydra.localhost/oauth2/token", diff --git a/oauth2/handler.go b/oauth2/handler.go index 8694dab1ef8..4d1aa700b4d 100644 --- a/oauth2/handler.go +++ b/oauth2/handler.go @@ -237,7 +237,7 @@ func (h *Handler) WellKnownHandler(w http.ResponseWriter, r *http.Request) { return } h.r.Writer().Write(w, r, &WellKnown{ - Issuer: strings.TrimRight(h.c.IssuerURL(r.Context()).String(), "/") + "/", + Issuer: h.c.IssuerURL(r.Context()).String(), AuthURL: h.c.OAuth2AuthURL(r.Context()).String(), TokenURL: h.c.OAuth2TokenURL(r.Context()).String(), JWKsURI: h.c.JWKSURL(r.Context()).String(), @@ -506,7 +506,7 @@ func (h *Handler) IntrospectHandler(w http.ResponseWriter, r *http.Request, _ ht Username: session.GetUsername(), Extra: session.Extra, Audience: audience, - Issuer: strings.TrimRight(h.c.IssuerURL(ctx).String(), "/") + "/", + Issuer: h.c.IssuerURL(ctx).String(), ObfuscatedSubject: obfuscated, TokenType: resp.GetAccessTokenType(), TokenUse: string(resp.GetTokenUse()), @@ -616,7 +616,7 @@ func (h *Handler) TokenHandler(w http.ResponseWriter, r *http.Request) { } session.ClientID = accessRequest.GetClient().GetID() session.KID = accessTokenKeyID - session.DefaultSession.Claims.Issuer = strings.TrimRight(h.c.IssuerURL(r.Context()).String(), "/") + "/" + session.DefaultSession.Claims.Issuer = h.c.IssuerURL(r.Context()).String() session.DefaultSession.Claims.IssuedAt = time.Now().UTC() var scopes = accessRequest.GetRequestedScopes() @@ -749,9 +749,8 @@ func (h *Handler) AuthHandler(w http.ResponseWriter, r *http.Request, _ httprout authorizeRequest.SetID(session.ID) claims := &jwt.IDTokenClaims{ - Subject: obfuscatedSubject, - Issuer: strings.TrimRight(h.c.IssuerURL(ctx).String(), "/") + "/", - + Subject: obfuscatedSubject, + Issuer: h.c.IssuerURL(ctx).String(), AuthTime: time.Time(session.AuthenticatedAt), RequestedAt: session.RequestedAt, Extra: session.Session.IDToken, diff --git a/oauth2/introspector_test.go b/oauth2/introspector_test.go index af9a77374e8..7c165a7fdaa 100644 --- a/oauth2/introspector_test.go +++ b/oauth2/introspector_test.go @@ -137,7 +137,7 @@ func TestIntrospectorSDK(t *testing.T) { assert.Equal(t, "alice", c.Sub) assert.Equal(t, now.Add(time.Hour).Unix(), c.Exp, "expires at") assert.Equal(t, now.Unix(), c.Iat, "issued at") - assert.Equal(t, "https://foobariss/", c.Iss, "issuer") + assert.Equal(t, "https://foobariss", c.Iss, "issuer") assert.Equal(t, map[string]interface{}{"foo": "bar"}, c.Ext) }, }, @@ -151,7 +151,7 @@ func TestIntrospectorSDK(t *testing.T) { assert.Equal(t, "alice", c.Sub) assert.Equal(t, now.Add(time.Hour).Unix(), c.Exp, "expires at") assert.Equal(t, now.Unix(), c.Iat, "issued at") - assert.Equal(t, "https://foobariss/", c.Iss, "issuer") + assert.Equal(t, "https://foobariss", c.Iss, "issuer") assert.Equal(t, map[string]interface{}{"foo": "bar"}, c.Ext) }, },