spring-projects / spring-projects/spring-security

Preserve the resource path in the default resource_metadata challenge

Open
#19,639 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: enhancement
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.