Expected Behavior
For a resource server mounted below the root, the default WWW-Authenticate challenge would ideally
follow RFC 9728 §3.1 and insert the well-known segment between host and resource path:
WWW-Authenticate: Bearer resource_metadata="https://host/.well-known/oauth-protected-resource/mcp"
Current Behavior
BearerTokenAuthenticationEntryPoint.getResourceMetadataParameter replaces the entire path, so every
resource is advertised at the root document:
WWW-Authenticate: Bearer resource_metadata="https://host/.well-known/oauth-protected-resource"
Context
OAuth2ProtectedResourceMetadataFilter already supports the suffixed form — it matches
/.well-known/oauth-protected-resource/** and resolveResourceIdentifier strips the well-known
segment, returning "resource": "https://host/mcp". Aligning the entry point's default with what the
filter already serves would make the two consistent out of the box.
#18542 added setResourceMetadataParameterResolver for exactly this case, so nothing is blocked. But
the resolver a non-root deployment needs is the framework's own default plus the endpoint path, which
every such application ends up reimplementing — Spring AI MCP servers (endpoint defaults to /mcp)
hit it by default.
Would a default that derives the path from the request, falling back to current behaviour at the root,
be in scope?
Context: Spring Boot 4.1.0 / Spring AI 2.0.0, oauth2ResourceServer with protectedResourceMetadata,
server mounted at /mcp.
(Note: This report was drafted in parts by Opus 5)
Expected Behavior
For a resource server mounted below the root, the default
WWW-Authenticatechallenge would ideallyfollow RFC 9728 §3.1 and insert the well-known segment between host and resource path:
WWW-Authenticate: Bearer resource_metadata="https://host/.well-known/oauth-protected-resource/mcp"
Current Behavior
BearerTokenAuthenticationEntryPoint.getResourceMetadataParameterreplaces the entire path, so everyresource is advertised at the root document:
WWW-Authenticate: Bearer resource_metadata="https://host/.well-known/oauth-protected-resource"
Context
OAuth2ProtectedResourceMetadataFilteralready supports the suffixed form — it matches/.well-known/oauth-protected-resource/**andresolveResourceIdentifierstrips the well-knownsegment, returning
"resource": "https://host/mcp". Aligning the entry point's default with what thefilter already serves would make the two consistent out of the box.
#18542 added
setResourceMetadataParameterResolverfor exactly this case, so nothing is blocked. Butthe resolver a non-root deployment needs is the framework's own default plus the endpoint path, which
every such application ends up reimplementing — Spring AI MCP servers (endpoint defaults to
/mcp)hit it by default.
Would a default that derives the path from the request, falling back to current behaviour at the root,
be in scope?
Context: Spring Boot 4.1.0 / Spring AI 2.0.0,
oauth2ResourceServerwithprotectedResourceMetadata,server mounted at
/mcp.(Note: This report was drafted in parts by Opus 5)