Skip to content

Commit ded6faa

Browse files
committed
Merge branch '1.3.x' into 1.4.x
2 parents 3cdc4f1 + 29472a1 commit ded6faa

File tree

2 files changed

+24
-21
lines changed

2 files changed

+24
-21
lines changed

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

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -137,6 +137,25 @@ public Authentication authenticate(Authentication authentication) throws Authent
137137
// In https://www.rfc-editor.org/rfc/rfc8628.html#section-3.5,
138138
// the following error codes are defined:
139139

140+
// expired_token
141+
// The "device_code" has expired, and the device authorization
142+
// session has concluded. The client MAY commence a new device
143+
// authorization request but SHOULD wait for user interaction before
144+
// restarting to avoid unnecessary polling.
145+
if (deviceCode.isExpired()) {
146+
if (!deviceCode.isInvalidated()) {
147+
// Invalidate the device code
148+
authorization = OAuth2Authorization.from(authorization).invalidate(deviceCode.getToken()).build();
149+
this.authorizationService.save(authorization);
150+
if (this.logger.isWarnEnabled()) {
151+
this.logger.warn(LogMessage.format("Invalidated device code used by registered client '%s'",
152+
authorization.getRegisteredClientId()));
153+
}
154+
}
155+
OAuth2Error error = new OAuth2Error(EXPIRED_TOKEN, null, DEVICE_ERROR_URI);
156+
throw new OAuth2AuthenticationException(error);
157+
}
158+
140159
// authorization_pending
141160
// The authorization request is still pending as the end user hasn't
142161
// yet completed the user-interaction steps (Section 3.3). The
@@ -165,23 +184,6 @@ public Authentication authenticate(Authentication authentication) throws Authent
165184
throw new OAuth2AuthenticationException(error);
166185
}
167186

168-
// expired_token
169-
// The "device_code" has expired, and the device authorization
170-
// session has concluded. The client MAY commence a new device
171-
// authorization request but SHOULD wait for user interaction before
172-
// restarting to avoid unnecessary polling.
173-
if (deviceCode.isExpired()) {
174-
// Invalidate the device code
175-
authorization = OAuth2Authorization.from(authorization).invalidate(deviceCode.getToken()).build();
176-
this.authorizationService.save(authorization);
177-
if (this.logger.isWarnEnabled()) {
178-
this.logger.warn(LogMessage.format("Invalidated device code used by registered client '%s'",
179-
authorization.getRegisteredClientId()));
180-
}
181-
OAuth2Error error = new OAuth2Error(EXPIRED_TOKEN, null, DEVICE_ERROR_URI);
182-
throw new OAuth2AuthenticationException(error);
183-
}
184-
185187
if (this.logger.isTraceEnabled()) {
186188
this.logger.trace("Validated device token request parameters");
187189
}

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2023 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -191,6 +191,7 @@ public void authenticateWhenUserCodeIsNotInvalidatedThenThrowOAuth2Authenticatio
191191
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
192192
Authentication authentication = createAuthentication(registeredClient);
193193
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
194+
.token(createDeviceCode())
194195
.token(createUserCode())
195196
.build();
196197
given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
@@ -209,7 +210,7 @@ public void authenticateWhenUserCodeIsNotInvalidatedThenThrowOAuth2Authenticatio
209210
}
210211

211212
@Test
212-
public void authenticateWhenDeviceCodeIsInvalidatedThenThrowOAuth2AuthenticationException() {
213+
public void authenticateWhenDeviceCodeAndUserCodeAreInvalidatedThenThrowOAuth2AuthenticationException() {
213214
RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
214215
Authentication authentication = createAuthentication(registeredClient);
215216
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
@@ -237,7 +238,7 @@ public void authenticateWhenDeviceCodeIsExpiredThenThrowOAuth2AuthenticationExce
237238
Authentication authentication = createAuthentication(registeredClient);
238239
OAuth2Authorization authorization = TestOAuth2Authorizations.authorization(registeredClient)
239240
.token(createExpiredDeviceCode())
240-
.token(createUserCode(), withInvalidated())
241+
.token(createUserCode())
241242
.build();
242243
given(this.authorizationService.findByToken(anyString(), any(OAuth2TokenType.class))).willReturn(authorization);
243244
// @formatter:off

0 commit comments

Comments
 (0)