Accept a case-insensitive "Bearer" keyword

The Authorization header was matched for OAuth2
against the "Bearer" keyword in a case sensitive
fashion.
According to RFC 2617, it should be case insensitive
and some oauth clients (including some earlier
versions of spring-security) expect it so.

This is the reactive counterpart to commit
63f2b6094f .

Fixes gh-6195
This commit is contained in:
Nicolas Le Bas 2018-12-01 11:43:40 -05:00
parent 60fc5381fe
commit ba8a337f9a
2 changed files with 13 additions and 2 deletions

View File

@ -43,7 +43,9 @@ import java.util.regex.Pattern;
*/ */
public class ServerBearerTokenAuthenticationConverter public class ServerBearerTokenAuthenticationConverter
implements ServerAuthenticationConverter { implements ServerAuthenticationConverter {
private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?<token>[a-zA-Z0-9-._~+/]+)=*$"); private static final Pattern authorizationPattern = Pattern.compile(
"^Bearer (?<token>[a-zA-Z0-9-._~+/]+)=*$",
Pattern.CASE_INSENSITIVE);
private boolean allowUriQueryParameter = false; private boolean allowUriQueryParameter = false;
@ -85,7 +87,7 @@ public class ServerBearerTokenAuthenticationConverter
private static String resolveFromAuthorizationHeader(HttpHeaders headers) { private static String resolveFromAuthorizationHeader(HttpHeaders headers) {
String authorization = headers.getFirst(HttpHeaders.AUTHORIZATION); String authorization = headers.getFirst(HttpHeaders.AUTHORIZATION);
if (StringUtils.hasText(authorization) && authorization.startsWith("Bearer")) { if (StringUtils.startsWithIgnoreCase(authorization, "bearer")) {
Matcher matcher = authorizationPattern.matcher(authorization); Matcher matcher = authorizationPattern.matcher(authorization);
if ( !matcher.matches() ) { if ( !matcher.matches() ) {

View File

@ -52,6 +52,15 @@ public class ServerBearerTokenAuthenticationConverterTests {
assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN); assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN);
} }
@Test
public void resolveWhenLowercaseHeaderIsPresentThenTokenIsResolved() {
MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest
.get("/")
.header(HttpHeaders.AUTHORIZATION, "bearer " + TEST_TOKEN);
assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN);
}
@Test @Test
public void resolveWhenNoHeaderIsPresentThenTokenIsNotResolved() { public void resolveWhenNoHeaderIsPresentThenTokenIsNotResolved() {
MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest