Repository navigation
Conversation
RFC 6750 §3.1 says a challenge for a request with no authentication information should not include an error code. requireBearerAuth now drops error and error_description when scope or resource_metadata is already present, and the Express adapter sends that same body. A rejected token still returns invalid_token, and a challenge with neither parameter keeps the error code. Fixes modelcontextprotocol#3124 Co-authored-by: Anandu Mv <Anandumv@users.noreply.github.com>
🦋 Changeset detectedLatest commit: 1584c28 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
JosephDoUrden
left a comment
There was a problem hiding this comment.
pulled the branch and ran it.
packages/server bearerAuth.test.ts 37/37, packages/middleware/express resourceServer.test.ts 16/16, test/e2e hosting-express.test.ts 25/25. merge against upstream/main clean, one commit behind (#3115). client side only branches on 403 insufficient_scope and use_dpop_nonce, so a 401 with no error param still starts the oauth flow.
one gap. rfc 6750 §3.1 names two no-error cases: no auth info at all, and "attempted using an unsupported authentication method". the pr covers the first only.
packages/server/src/server/middleware/bearerAuth.ts:168-170 still throws plain InvalidToken for a non-bearer scheme. probe with resource_metadata set: no header gives Bearer resource_metadata="..." and an empty body. Basic dXNlcjpwYXNz gives Bearer error="invalid_token", error_description="Invalid Authorization header format..." and an error body. Digest behaves like Basic.
a client sending Basic has not presented a bearer token, so telling it the token is invalid is the same mismatch #3124 is about. Bearer with an empty token is arguably malformed and can keep the error. suggest the scheme-mismatch branch throws MissingAuthorizationError too, plus one test.
otherwise the shape looks right: the error is only dropped when scope or resource_metadata keeps the challenge non-empty, and the express adapter now reuses the core body. fine to land after that tweak.
Closes #3124.
Summary
requireBearerAuthanswered a request with noAuthorizationheader as401 invalid_token. RFC 6750 §3.1 says a resource server should not include an error code when the request has no authentication information.The challenge now omits
erroranderror_descriptionwhenscopeorresource_metadatais already present, and the JSON body is{}so it matches the header. The Express adapter sends that same body. A presented token that fails verification is unchanged. When neitherscopenorresource_metadatais configured, the challenge still includesinvalid_token, so it is never a bareBearer.Tests
@modelcontextprotocol/serverand@modelcontextprotocol/expressfor scope only,resource_metadataonly, both, neither, a rejected token, and a malformedAuthorizationheader.hosting:auth:missing-401andhosting:auth:query-token-ignoredexpect the credential-less challenge.pnpm lint:all,pnpm build:all, andpnpm test:allpass. The bearer-auth and bearer-auth-web examples pass on the modern and legacy HTTP legs.