Skip to content

Commit b51e184

Browse files
TJReinertTeddy Reinert
authored andcommitted
Allow custom header during bearer token extraction
Added ability to specify the header that ServerBearerTokenAuthenticationConverter and DefaultBearerTokenResolver use to extract a Bearer Token. Fixes gh-8337
1 parent 6d45ec5 commit b51e184

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolver.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
4545

4646
private boolean allowUriQueryParameter = false;
4747

48+
private String bearerTokenHeaderName = HttpHeaders.AUTHORIZATION;
49+
4850
/**
4951
* {@inheritDoc}
5052
*/
@@ -85,8 +87,21 @@ public void setAllowUriQueryParameter(boolean allowUriQueryParameter) {
8587
this.allowUriQueryParameter = allowUriQueryParameter;
8688
}
8789

88-
private static String resolveFromAuthorizationHeader(HttpServletRequest request) {
89-
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
90+
/**
91+
* Set this value to configure what header is checked when resolving a Bearer Token.
92+
* This value is defaulted to {@link HttpHeaders#AUTHORIZATION}.
93+
*
94+
* This allows other headers to be used as the Bearer Token source such as {@link HttpHeaders#PROXY_AUTHORIZATION}
95+
*
96+
* @param bearerTokenHeaderName the header to check when retrieving the Bearer Token.
97+
* @since 5.4
98+
*/
99+
public void setBearerTokenHeaderName(String bearerTokenHeaderName) {
100+
this.bearerTokenHeaderName = bearerTokenHeaderName;
101+
}
102+
103+
private String resolveFromAuthorizationHeader(HttpServletRequest request) {
104+
String authorization = request.getHeader(this.bearerTokenHeaderName);
90105
if (StringUtils.startsWithIgnoreCase(authorization, "bearer")) {
91106
Matcher matcher = authorizationPattern.matcher(authorization);
92107

oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverter.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public class ServerBearerTokenAuthenticationConverter
5050
Pattern.CASE_INSENSITIVE);
5151

5252
private boolean allowUriQueryParameter = false;
53+
private String bearerTokenHeaderName = HttpHeaders.AUTHORIZATION;
5354

5455
public Mono<Authentication> convert(ServerWebExchange exchange) {
5556
return Mono.justOrEmpty(token(exchange.getRequest()))
@@ -90,8 +91,21 @@ public void setAllowUriQueryParameter(boolean allowUriQueryParameter) {
9091
this.allowUriQueryParameter = allowUriQueryParameter;
9192
}
9293

93-
private static String resolveFromAuthorizationHeader(HttpHeaders headers) {
94-
String authorization = headers.getFirst(HttpHeaders.AUTHORIZATION);
94+
/**
95+
* Set this value to configure what header is checked when resolving a Bearer Token.
96+
* This value is defaulted to {@link HttpHeaders#AUTHORIZATION}.
97+
*
98+
* This allows other headers to be used as the Bearer Token source such as {@link HttpHeaders#PROXY_AUTHORIZATION}
99+
*
100+
* @param bearerTokenHeaderName the header to check when retrieving the Bearer Token.
101+
* @since 5.4
102+
*/
103+
public void setBearerTokenHeaderName(String bearerTokenHeaderName) {
104+
this.bearerTokenHeaderName = bearerTokenHeaderName;
105+
}
106+
107+
private String resolveFromAuthorizationHeader(HttpHeaders headers) {
108+
String authorization = headers.getFirst(this.bearerTokenHeaderName);
95109
if (StringUtils.startsWithIgnoreCase(authorization, "bearer")) {
96110
Matcher matcher = authorizationPattern.matcher(authorization);
97111

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/DefaultBearerTokenResolverTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* @author Vedran Pavic
3434
*/
3535
public class DefaultBearerTokenResolverTests {
36-
36+
private static final String CUSTOM_HEADER = "custom-header";
3737
private static final String TEST_TOKEN = "test-token";
3838

3939
private DefaultBearerTokenResolver resolver;
@@ -51,6 +51,15 @@ public void resolveWhenValidHeaderIsPresentThenTokenIsResolved() {
5151
assertThat(this.resolver.resolve(request)).isEqualTo(TEST_TOKEN);
5252
}
5353

54+
@Test
55+
public void resolveWhenCustomDefinedHeaderIsValidAndPresentThenTokenIsResolved() {
56+
this.resolver.setBearerTokenHeaderName(CUSTOM_HEADER);
57+
MockHttpServletRequest request = new MockHttpServletRequest();
58+
request.addHeader(CUSTOM_HEADER, "Bearer " + TEST_TOKEN);
59+
60+
assertThat(this.resolver.resolve(request)).isEqualTo(TEST_TOKEN);
61+
}
62+
5463
@Test
5564
public void resolveWhenLowercaseHeaderIsPresentThenTokenIsResolved() {
5665
MockHttpServletRequest request = new MockHttpServletRequest();

oauth2/oauth2-resource-server/src/test/java/org/springframework/security/oauth2/server/resource/web/server/ServerBearerTokenAuthenticationConverterTests.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
* @since 5.1
3939
*/
4040
public class ServerBearerTokenAuthenticationConverterTests {
41+
private static final String CUSTOM_HEADER = "custom-header";
4142
private static final String TEST_TOKEN = "test-token";
4243

4344
private ServerBearerTokenAuthenticationConverter converter;
@@ -56,6 +57,16 @@ public void resolveWhenValidHeaderIsPresentThenTokenIsResolved() {
5657
assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN);
5758
}
5859

60+
@Test
61+
public void resolveWhenCustomDefinedHeaderIsValidAndPresentThenTokenIsResolved() {
62+
this.converter.setBearerTokenHeaderName(CUSTOM_HEADER);
63+
MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest
64+
.get("/")
65+
.header(CUSTOM_HEADER, "Bearer " + TEST_TOKEN);
66+
67+
assertThat(convertToToken(request).getToken()).isEqualTo(TEST_TOKEN);
68+
}
69+
5970
// gh-7011
6071
@Test
6172
public void resolveWhenValidHeaderIsEmptyStringThenTokenIsResolved() {

0 commit comments

Comments
 (0)