浏览代码

Merge branch '6.2.x' into 6.3.x

Closes gh-16036
Steve Riesenberg 9 月之前
父节点
当前提交
b9d5493913

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -57,13 +57,18 @@ public final class DefaultBearerTokenResolver implements BearerTokenResolver {
 				? resolveFromRequestParameters(request) : null;
 		if (authorizationHeaderToken != null) {
 			if (parameterToken != null) {
-				final BearerTokenError error = BearerTokenErrors
+				BearerTokenError error = BearerTokenErrors
 					.invalidRequest("Found multiple bearer tokens in the request");
 				throw new OAuth2AuthenticationException(error);
 			}
 			return authorizationHeaderToken;
 		}
 		if (parameterToken != null && isParameterTokenEnabledForRequest(request)) {
+			if (!StringUtils.hasText(parameterToken)) {
+				BearerTokenError error = BearerTokenErrors
+					.invalidRequest("The requested token parameter is an empty string");
+				throw new OAuth2AuthenticationException(error);
+			}
 			return parameterToken;
 		}
 		return null;

+ 6 - 1
oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/authentication/ServerBearerTokenAuthenticationConverter.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -78,6 +78,11 @@ public class ServerBearerTokenAuthenticationConverter implements ServerAuthentic
 			return authorizationHeaderToken;
 		}
 		if (parameterToken != null && isParameterTokenSupportedForRequest(request)) {
+			if (!StringUtils.hasText(parameterToken)) {
+				BearerTokenError error = BearerTokenErrors
+					.invalidRequest("The requested token parameter is an empty string");
+				throw new OAuth2AuthenticationException(error);
+			}
 			return parameterToken;
 		}
 		return null;

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -21,8 +21,11 @@ import java.util.Base64;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import org.springframework.http.HttpStatus;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.server.resource.BearerTokenError;
+import org.springframework.security.oauth2.server.resource.BearerTokenErrorCodes;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -258,4 +261,35 @@ public class DefaultBearerTokenResolverTests {
 		assertThat(this.resolver.resolve(request)).isNull();
 	}
 
+	@Test
+	public void resolveWhenQueryParameterIsPresentAndEmptyStringThenTokenIsNotResolved() {
+		this.resolver.setAllowUriQueryParameter(true);
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		request.setMethod("GET");
+		request.addParameter("access_token", "");
+		assertThatExceptionOfType(OAuth2AuthenticationException.class).isThrownBy(() -> this.resolver.resolve(request))
+			.withMessageContaining("The requested token parameter is an empty string")
+			.satisfies((e) -> {
+				BearerTokenError error = (BearerTokenError) e.getError();
+				assertThat(error.getErrorCode()).isEqualTo(BearerTokenErrorCodes.INVALID_REQUEST);
+				assertThat(error.getHttpStatus()).isEqualTo(HttpStatus.BAD_REQUEST);
+			});
+	}
+
+	@Test
+	public void resolveWhenFormParameterIsPresentAndEmptyStringThenTokenIsNotResolved() {
+		this.resolver.setAllowFormEncodedBodyParameter(true);
+		MockHttpServletRequest request = new MockHttpServletRequest();
+		request.setMethod("POST");
+		request.setContentType("application/x-www-form-urlencoded");
+		request.addParameter("access_token", "");
+		assertThatExceptionOfType(OAuth2AuthenticationException.class).isThrownBy(() -> this.resolver.resolve(request))
+			.withMessageContaining("The requested token parameter is an empty string")
+			.satisfies((e) -> {
+				BearerTokenError error = (BearerTokenError) e.getError();
+				assertThat(error.getErrorCode()).isEqualTo(BearerTokenErrorCodes.INVALID_REQUEST);
+				assertThat(error.getHttpStatus()).isEqualTo(HttpStatus.BAD_REQUEST);
+			});
+	}
+
 }

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

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2021 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -187,9 +187,9 @@ public class ServerBearerTokenAuthenticationConverterTests {
 				.isThrownBy(() -> convertToToken(request))
 				.satisfies((ex) -> {
 					BearerTokenError error = (BearerTokenError) ex.getError();
-					assertThat(error.getErrorCode()).isEqualTo(BearerTokenErrorCodes.INVALID_TOKEN);
+					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.UNAUTHORIZED);
+					assertThat(error.getHttpStatus()).isEqualTo(HttpStatus.BAD_REQUEST);
 				});
 		// @formatter:on
 	}