Skip to content

Device Access Token Response with expired device code returns "authorization_pending" and not "expired_token" #1885

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nwholloway opened this issue Jan 23, 2025 · 2 comments
Assignees
Labels
status: duplicate A duplicate of another issue type: bug A general bug

Comments

@nwholloway
Copy link
Contributor

If you make a valid Device Access Token Request and do not grant/deny consent from the provided verification_uri_complete, then all polls of the token endpoint will indefinitely return authorization_pending.

If you have a client which will continue polling while receiving authorization_pending (rather than using expires_in), then the client will poll forever.

The reason for this is that authorization_pending is always returned if the user code is not invalidated (Line 150), irrespective of the age of the device code.

The only operation that will invalidate the user code is either granting/denying consent from the device verification consent page.

I believe that the check for the device code expiring (Line 173) should be moved before the check for user code invalidation.

The test authenticateWhenDeviceCodeIsExpiredThenThrowOAuth2AuthenticationException only passes because the user code is created in an invalidated state.

The following update to the test demonstrates the failure.

        @Test
        public void authenticateWhenDeviceCodeIsExpiredThenThrowOAuth2AuthenticationException() {
                RegisteredClient registeredClient = TestRegisteredClients.registeredClient().build();
                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
                assertThatExceptionOfType(OAuth2AuthenticationException.class)
                                .isThrownBy(() -> this.authenticationProvider.authenticate(authentication))
                                .extracting(OAuth2AuthenticationException::getError)

This was previously raised in #1556, but that issue was closed as the feedback requested was not provided.

@nwholloway nwholloway added the type: bug A general bug label Jan 23, 2025
@jgrandja
Copy link
Collaborator

@nwholloway Thank you for all the details! I've confirmed that this is indeed a bug. Would you be interested in submitting a fix for this?

@jgrandja jgrandja added this to the 1.3.5 milestone Jan 29, 2025
@jgrandja jgrandja moved this to Prioritized in Spring Security Team Jan 29, 2025
@nwholloway
Copy link
Contributor Author

I'll submit a fix for this soon.

nwholloway added a commit to nwholloway/spring-authorization-server that referenced this issue Jan 31, 2025
nwholloway added a commit to nwholloway/spring-authorization-server that referenced this issue Jan 31, 2025
nwholloway added a commit to nwholloway/spring-authorization-server that referenced this issue Jan 31, 2025
@jgrandja jgrandja added the status: duplicate A duplicate of another issue label Feb 5, 2025
@jgrandja jgrandja removed this from the 1.3.5 milestone Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants