Compare auth server metadata issuer ignoring trailing slash (#955)

oauthex/auth_meta.go: fixes metadata issuer comparison to ignore
trailing slash difference

Google's gmail MCP server returns `https://accounts.google.com/` as the
Authorization Server in the Protected Resource Metadata, but returns
`https://accounts.google.com` in the Auth Server Metadata. This causes a
comparison failure per rfc8414 section-3.3: Authorization Server
Metadata Validation. The authorization server URL is meant to be a base
to build other URLs from, it does not seem necessary to enforce that the
trailing slash (or lack thereof) matches with the issuer URL. Please see
#953 for more details.

Fixes #953

---------

Co-authored-by: Guglielmo Colombo <guglielmoc@google.com>
This commit is contained in:
Jon 2026-05-14 00:26:57 -07:00 • committed by GitHub
commit da3535b678
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 4 deletions

View file

@ -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)
}

View file

@ -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()