diff --git a/oauthex/auth_meta.go b/oauthex/auth_meta.go index df1a0aa8..255aca92 100644 --- a/oauthex/auth_meta.go +++ b/oauthex/auth_meta.go @@ -12,6 +12,7 @@ import ( "errors" "fmt" "net/http" + "strings" ) // AuthServerMeta represents the metadata for an OAuth 2.0 authorization server, @@ -145,7 +146,7 @@ func GetAuthServerMeta(ctx context.Context, metadataURL, issuer string, c *http. } return nil, fmt.Errorf("%v", err) // Do not expose error types. } - if asm.Issuer != issuer { + if strings.TrimRight(asm.Issuer, "/") != strings.TrimRight(issuer, "/") { // Validate the Issuer field (see RFC 8414, section 3.3). return nil, fmt.Errorf("metadata issuer %q does not match issuer URL %q", asm.Issuer, issuer) } diff --git a/oauthex/auth_meta_test.go b/oauthex/auth_meta_test.go index f390676f..5c6c4ad3 100644 --- a/oauthex/auth_meta_test.go +++ b/oauthex/auth_meta_test.go @@ -35,9 +35,10 @@ func TestAuthMetaParse(t *testing.T) { func TestGetAuthServerMetaPKCESupport(t *testing.T) { ctx := context.Background() tests := []struct { - name string - hasPKCESupport bool - wantError string + name string + hasPKCESupport bool + wantError string + issuerWithTrailingSlash bool }{ { name: "server_with_pkce_support", @@ -48,6 +49,12 @@ func TestGetAuthServerMetaPKCESupport(t *testing.T) { hasPKCESupport: false, wantError: "does not implement PKCE", }, + { + // ProtectedResourceMetadata may contain AuthorizationServers with a trailing slash (see Issue #953) + name: "issuer_with_trailing_slash", + hasPKCESupport: true, + issuerWithTrailingSlash: true, + }, } for _, tt := range tests { @@ -85,6 +92,9 @@ func TestGetAuthServerMetaPKCESupport(t *testing.T) { u, _ := url.Parse(ts.URL) issuer := "https://localhost:" + u.Port() metadataURL := issuer + "/.well-known/oauth-authorization-server" + if tt.issuerWithTrailingSlash { + issuer += "/" + } // The fake server presents a cert for example.com; set ServerName accordingly. httpClient := ts.Client()