Skip to content

DefaultBearerTokenResolver rejects RFC-legal multi-space Authorization header #19500

Description

@daniel-huss

Component: spring-security-oauth2-resource-server · Affects: 6.5.x, 7.1.0, current main

Problem

DefaultBearerTokenResolver matches the header against
^Bearer (?<token>[a-zA-Z0-9-._~+/]+=*)$ — a single literal space. RFC 6750 §2.1
(credentials = "Bearer" 1*SP b64token) and RFC 9110 §11.6.2 (1*SP) allow one or more
spaces. A conformant Authorization: Bearer␣␣<token> is therefore rejected with
invalid_token / "Bearer token is malformed".

Reproduce

Send an otherwise valid request with two spaces after Bearer:

Authorization: Bearer  eyJhbGciOi...

→ HTTP 401, WWW-Authenticate: Bearer error="invalid_token", error_description="Bearer token is malformed".

The token never reaches the decoder; it fails at header resolution.

Expected

Per 1*SP, the token is resolved and validated normally (→ 200 for a valid token).

Notes

  • Masked by some servlet containers: Undertow (2.3.24) collapses the double space to one so
    Spring accepts it; Jetty preserves it verbatim so Spring rejects it. Switching containers
    surfaces the latent rejection with no client change.
  • Regex identical in 6.5.11 and 7.1.0.

Suggested fix

Match 1*SP:

Pattern.compile("^Bearer +(?<token>[a-zA-Z0-9-._~+/]+=*)$", Pattern.CASE_INSENSITIVE);

Failing test

@Test
public void resolveWhenHeaderHasMultipleSpacesBeforeTokenThenTokenIsResolved() {
	// RFC 6750 section 2.1: credentials = "Bearer" 1*SP b64token (one or more spaces)
	MockHttpServletRequest request = new MockHttpServletRequest();
	request.addHeader("Authorization", "Bearer  " + TEST_TOKEN);
	assertThat(this.resolver.resolve(request)).isEqualTo(TEST_TOKEN);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions