From ba8a337f9a650fe0010b95a925af238409122756 Mon Sep 17 00:00:00 2001 From: Nicolas Le Bas Date: Sat, 1 Dec 2018 11:43:40 -0500 Subject: [PATCH] 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 63f2b6094f59cc9ded6a83ac3def4a1726890a8b . Fixes gh-6195 --- .../server/ServerBearerTokenAuthenticationConverter.java | 6 ++++-- .../ServerBearerTokenAuthenticationConverterTests.java | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java index 855d1d43e11..15c3b45caa9 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java @@ -43,7 +43,9 @@ */ public class ServerBearerTokenAuthenticationConverter implements ServerAuthenticationConverter { - private static final Pattern authorizationPattern = Pattern.compile("^Bearer (?[a-zA-Z0-9-._~+/]+)=*$"); + private static final Pattern authorizationPattern = Pattern.compile( + "^Bearer (?[a-zA-Z0-9-._~+/]+)=*$", + Pattern.CASE_INSENSITIVE); private boolean allowUriQueryParameter = false; @@ -85,7 +87,7 @@ public void setAllowUriQueryParameter(boolean allowUriQueryParameter) { private static String resolveFromAuthorizationHeader(HttpHeaders headers) { String authorization = headers.getFirst(HttpHeaders.AUTHORIZATION); - if (StringUtils.hasText(authorization) && authorization.startsWith("Bearer")) { + if (StringUtils.startsWithIgnoreCase(authorization, "bearer")) { Matcher matcher = authorizationPattern.matcher(authorization); if ( !matcher.matches() ) { diff --git a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java index f4b9a099676..6aacc299135 100644 --- a/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java +++ b/oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java @@ -52,6 +52,15 @@ public void resolveWhenValidHeaderIsPresentThenTokenIsResolved() { 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 public void resolveWhenNoHeaderIsPresentThenTokenIsNotResolved() { MockServerHttpRequest.BaseBuilder request = MockServerHttpRequest