Skip to content

Commit

Permalink
Check for multiple access tokens per rfc 6750
Browse files Browse the repository at this point in the history
Check for multiple access tokens on the ServerHttpRequest rather than get get first. If multiples are found throw a OAuth2AuthenticationException.

Closes gh-5708
  • Loading branch information
DarrenForsythe authored and jzheaux committed Sep 28, 2021
1 parent 770c57e commit 5556b82
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package org.springframework.security.oauth2.server.resource.web.server;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -30,6 +31,7 @@
import org.springframework.security.oauth2.server.resource.BearerTokenError;
import org.springframework.security.oauth2.server.resource.BearerTokenErrors;
import org.springframework.security.web.server.authentication.ServerAuthenticationConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;

Expand Down Expand Up @@ -65,7 +67,8 @@ public Mono<Authentication> convert(ServerWebExchange exchange) {

private String token(ServerHttpRequest request) {
String authorizationHeaderToken = resolveFromAuthorizationHeader(request.getHeaders());
String parameterToken = request.getQueryParams().getFirst("access_token");
String parameterToken = resolveAccessTokenFromRequest(request);

if (authorizationHeaderToken != null) {
if (parameterToken != null) {
BearerTokenError error = BearerTokenErrors
Expand All @@ -80,6 +83,20 @@ private String token(ServerHttpRequest request) {
return null;
}

private static String resolveAccessTokenFromRequest(ServerHttpRequest request) {
List<String> parameterTokens = request.getQueryParams().get("access_token");
if (CollectionUtils.isEmpty(parameterTokens)) {
return null;
}
if (parameterTokens.size() == 1) {
return parameterTokens.get(0);
}

BearerTokenError error = BearerTokenErrors.invalidRequest("Found multiple bearer tokens in the request");
throw new OAuth2AuthenticationException(error);

}

/**
* Set if transport of access token using URI query parameter is supported. Defaults
* to {@code false}.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2020 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -203,6 +203,20 @@ public void resolveWhenQueryParameterIsPresentAndNotSupportedThenTokenIsNotResol
assertThat(convertToToken(request)).isNull();
}

@Test
void resolveWhenQueryParameterHasMultipleAccessTokensThenOAuth2AuthenticationException() {
MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest.get("/").queryParam("access_token",
TEST_TOKEN, TEST_TOKEN);
assertThatExceptionOfType(OAuth2AuthenticationException.class).isThrownBy(() -> convertToToken(request))
.satisfies((ex) -> {
BearerTokenError error = (BearerTokenError) ex.getError();
assertThat(error.getErrorCode()).isEqualTo(BearerTokenErrorCodes.INVALID_REQUEST);
assertThat(error.getUri()).isEqualTo("https://tools.ietf.org/html/rfc6750#section-3.1");
assertThat(error.getHttpStatus()).isEqualTo(HttpStatus.BAD_REQUEST);
});

}

private BearerTokenAuthenticationToken convertToToken(MockServerHttpRequest.BaseBuilder<?> request) {
return convertToToken(request.build());
}
Expand Down

0 comments on commit 5556b82

Please sign in to comment.