Browse Source

Check for multiple access tokens per rfc 6750

Check for multiple access tokens on the ServerHttpRequest rather than get get first. If multiples are found throw a OAuth2AuthenticationException.

Closes gh-5708
Darren Forsythe 4 năm trước cách đây
mục cha
commit
5556b821e3

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

@@ -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.
@@ -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;
 
@@ -30,6 +31,7 @@ import org.springframework.security.oauth2.server.resource.BearerTokenAuthentica
 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;
 
@@ -65,7 +67,8 @@ public class ServerBearerTokenAuthenticationConverter implements ServerAuthentic
 
 	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
@@ -80,6 +83,20 @@ public class ServerBearerTokenAuthenticationConverter implements ServerAuthentic
 		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}.

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

@@ -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.
@@ -203,6 +203,20 @@ public class ServerBearerTokenAuthenticationConverterTests {
 		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());
 	}