Преглед изворни кода

Merge branch '1.3.x' into 1.4.x

Joe Grandja пре 6 месеци
родитељ
комит
ded6faae76

+ 20 - 18
oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceCodeAuthenticationProvider.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2024 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -137,6 +137,25 @@ public final class OAuth2DeviceCodeAuthenticationProvider implements Authenticat
 		// In https://www.rfc-editor.org/rfc/rfc8628.html#section-3.5,
 		// the following error codes are defined:
 
+		// expired_token
+		// The "device_code" has expired, and the device authorization
+		// session has concluded. The client MAY commence a new device
+		// authorization request but SHOULD wait for user interaction before
+		// restarting to avoid unnecessary polling.
+		if (deviceCode.isExpired()) {
+			if (!deviceCode.isInvalidated()) {
+				// Invalidate the device code
+				authorization = OAuth2Authorization.from(authorization).invalidate(deviceCode.getToken()).build();
+				this.authorizationService.save(authorization);
+				if (this.logger.isWarnEnabled()) {
+					this.logger.warn(LogMessage.format("Invalidated device code used by registered client '%s'",
+							authorization.getRegisteredClientId()));
+				}
+			}
+			OAuth2Error error = new OAuth2Error(EXPIRED_TOKEN, null, DEVICE_ERROR_URI);
+			throw new OAuth2AuthenticationException(error);
+		}
+
 		// authorization_pending
 		// The authorization request is still pending as the end user hasn't
 		// yet completed the user-interaction steps (Section 3.3). The
@@ -165,23 +184,6 @@ public final class OAuth2DeviceCodeAuthenticationProvider implements Authenticat
 			throw new OAuth2AuthenticationException(error);
 		}
 
-		// expired_token
-		// The "device_code" has expired, and the device authorization
-		// session has concluded. The client MAY commence a new device
-		// authorization request but SHOULD wait for user interaction before
-		// restarting to avoid unnecessary polling.
-		if (deviceCode.isExpired()) {
-			// Invalidate the device code
-			authorization = OAuth2Authorization.from(authorization).invalidate(deviceCode.getToken()).build();
-			this.authorizationService.save(authorization);
-			if (this.logger.isWarnEnabled()) {
-				this.logger.warn(LogMessage.format("Invalidated device code used by registered client '%s'",
-						authorization.getRegisteredClientId()));
-			}
-			OAuth2Error error = new OAuth2Error(EXPIRED_TOKEN, null, DEVICE_ERROR_URI);
-			throw new OAuth2AuthenticationException(error);
-		}
-
 		if (this.logger.isTraceEnabled()) {
 			this.logger.trace("Validated device token request parameters");
 		}

+ 4 - 3
oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceCodeAuthenticationProviderTests.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2020-2023 the original author or authors.
+ * Copyright 2020-2025 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.
@@ -191,6 +191,7 @@ public class OAuth2DeviceCodeAuthenticationProviderTests {
 		RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
 		Authentication authentication = createAuthentication(registeredClient);
 		OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
+			.token(createDeviceCode())
 			.token(createUserCode())
 			.build();
 		given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
@@ -209,7 +210,7 @@ public class OAuth2DeviceCodeAuthenticationProviderTests {
 	}
 
 	@Test
-	public void authenticateWhenDeviceCodeIsInvalidatedThenThrowOAuth2AuthenticationException() {
+	public void authenticateWhenDeviceCodeAndUserCodeAreInvalidatedThenThrowOAuth2AuthenticationException() {
 		RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
 		Authentication authentication = createAuthentication(registeredClient);
 		OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
@@ -237,7 +238,7 @@ public class OAuth2DeviceCodeAuthenticationProviderTests {
 		Authentication authentication = createAuthentication(registeredClient);
 		OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
 			.token(createExpiredDeviceCode())
-			.token(createUserCode(), withInvalidated())
+			.token(createUserCode())
 			.build();
 		given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
 		// @formatter:off