spring-projects / spring-projects/spring-security
Preserve the resource path in the default resource_metadata challenge
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in BearerTokenAuthenticationEntryPoint.getResourceMetadataParameter and compare its path handling with OAuth2ProtectedResourceMetadataFilter's suffixed-path matching and resolveResourceIdentifier behavior. Verify the default challenge preserves a mounted resource path such as /mcp while retaining the current root behavior, and add or update coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- authentication, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100