Browse Source

Merge branch '1.3.x' into 1.4.x

pull/1912/head
Joe Grandja 10 months ago
parent
commit
ded6faae76
  1. 38
      oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceCodeAuthenticationProvider.java
  2. 7
      oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceCodeAuthenticationProviderTests.java

38
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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, // In https://www.rfc-editor.org/rfc/rfc8628.html#section-3.5,
// the following error codes are defined: // 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 // authorization_pending
// The authorization request is still pending as the end user hasn't // The authorization request is still pending as the end user hasn't
// yet completed the user-interaction steps (Section 3.3). The // yet completed the user-interaction steps (Section 3.3). The
@ -165,23 +184,6 @@ public final class OAuth2DeviceCodeAuthenticationProvider implements Authenticat
throw new OAuth2AuthenticationException(error); 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()) { if (this.logger.isTraceEnabled()) {
this.logger.trace("Validated device token request parameters"); this.logger.trace("Validated device token request parameters");
} }

7
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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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(); RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
Authentication authentication = createAuthentication(registeredClient); Authentication authentication = createAuthentication(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient) OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
.token(createDeviceCode())
.token(createUserCode()) .token(createUserCode())
.build(); .build();
given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization); given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
@ -209,7 +210,7 @@ public class OAuth2DeviceCodeAuthenticationProviderTests {
} }
@Test @Test
public void authenticateWhenDeviceCodeIsInvalidatedThenThrowOAuth2AuthenticationException() { public void authenticateWhenDeviceCodeAndUserCodeAreInvalidatedThenThrowOAuth2AuthenticationException() {
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build(); RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
Authentication authentication = createAuthentication(registeredClient); Authentication authentication = createAuthentication(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient) OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
@ -237,7 +238,7 @@ public class OAuth2DeviceCodeAuthenticationProviderTests {
Authentication authentication = createAuthentication(registeredClient); Authentication authentication = createAuthentication(registeredClient);
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient) OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
.token(createExpiredDeviceCode()) .token(createExpiredDeviceCode())
.token(createUserCode(), withInvalidated()) .token(createUserCode())
.build(); .build();
given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization); given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
// @formatter:off // @formatter:off

Loading…
Cancel
Save