Skip to content

Commit 5e0605b

Browse files
committed
Validate bearer token for all flows
Fixes gh-7011
1 parent 23a7c30 commit 5e0605b

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

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

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
3939
private static final Pattern authorizationPattern = Pattern.compile(
4040
"^Bearer (?<token>[a-zA-Z0-9-._~+/]+)=*$",
4141
Pattern.CASE_INSENSITIVE);
42+
private static final Pattern queryParametersPattern = Pattern.compile(
43+
"^(?<token>[a-zA-Z0-9-._~+/]+)=*$",
44+
Pattern.CASE_INSENSITIVE);
4245

4346
private boolean allowFormEncodedBodyParameter = false;
4447

@@ -90,17 +93,7 @@ public void setAllowUriQueryParameter(boolean allowUriQueryParameter) {
9093
private static String resolveFromAuthorizationHeader(HttpServletRequest request) {
9194
String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
9295
if (StringUtils.startsWithIgnoreCase(authorization, "bearer")) {
93-
Matcher matcher = authorizationPattern.matcher(authorization);
94-
95-
if (!matcher.matches()) {
96-
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN,
97-
HttpStatus.UNAUTHORIZED,
98-
"Bearer token is malformed",
99-
"https://tools.ietf.org/html/rfc6750#section-3.1");
100-
throw new OAuth2AuthenticationException(error);
101-
}
102-
103-
return matcher.group("token");
96+
return validateToken(authorization, authorizationPattern);
10497
}
10598
return null;
10699
}
@@ -112,7 +105,7 @@ private static String resolveFromRequestParameters(HttpServletRequest request) {
112105
}
113106

114107
if (values.length == 1) {
115-
return values[0];
108+
return validateToken(values[0], queryParametersPattern);
116109
}
117110

118111
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_REQUEST,
@@ -126,4 +119,18 @@ private boolean isParameterTokenSupportedForRequest(HttpServletRequest request)
126119
return ((this.allowFormEncodedBodyParameter && "POST".equals(request.getMethod()))
127120
|| (this.allowUriQueryParameter && "GET".equals(request.getMethod())));
128121
}
122+
123+
private static String validateToken(String token, Pattern pattern) {
124+
Matcher matcher = pattern.matcher(token);
125+
126+
if (!matcher.matches()) {
127+
BearerTokenError error = new BearerTokenError(BearerTokenErrorCodes.INVALID_TOKEN,
128+
HttpStatus.UNAUTHORIZED,
129+
"Bearer token is malformed",
130+
"https://tools.ietf.org/html/rfc6750#section-3.1");
131+
throw new OAuth2AuthenticationException(error);
132+
}
133+
134+
return matcher.group("token");
135+
}
129136
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,28 @@ public void resolveWhenQueryParameterIsPresentAndNotSupportedThenTokenIsNotResol
165165

166166
assertThat(this.resolver.resolve(request)).isNull();
167167
}
168+
169+
@Test
170+
public void resolveWhenQueryParameterIsPresentWithMissingTokenThenAuthenticationExceptionIsThrown() {
171+
this.resolver.setAllowUriQueryParameter(true);
172+
173+
MockHttpServletRequest request = new MockHttpServletRequest();
174+
request.setMethod("GET");
175+
request.addParameter("access_token", "");
176+
177+
assertThatCode(() -> this.resolver.resolve(request)).isInstanceOf(OAuth2AuthenticationException.class)
178+
.hasMessageContaining(("Bearer token is malformed"));
179+
}
180+
181+
@Test
182+
public void resolveWhenQueryParameterWithInvalidCharactersIsPresentThenAuthenticationExceptionIsThrown() {
183+
this.resolver.setAllowUriQueryParameter(true);
184+
185+
MockHttpServletRequest request = new MockHttpServletRequest();
186+
request.setMethod("GET");
187+
request.addParameter("access_token", "an\"invalid\"token");
188+
189+
assertThatCode(() -> this.resolver.resolve(request)).isInstanceOf(OAuth2AuthenticationException.class)
190+
.hasMessageContaining(("Bearer token is malformed"));
191+
}
168192
}

0 commit comments

Comments
 (0)