Skip to content

Fix device authorization flow without requested scopes#19257

Open
therepanic wants to merge 1 commit into
spring-projects:mainfrom
therepanic:handle-empty-authorities-in-device-authorization-consent
Open

Fix device authorization flow without requested scopes#19257
therepanic wants to merge 1 commit into
spring-projects:mainfrom
therepanic:handle-empty-authorities-in-device-authorization-consent

Conversation

@therepanic

@therepanic therepanic commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

The main issue is inconsistent behavior. A device_authorization request without a scope is always accepted, but then, during the consent phase, if authorities is empty, we always get an access_denied error. However, would not it make sense to continue processing when both scope and authorities are empty?

The scope parameter itself is optional according to RFC-8628. There is also a note attached to it that refers to Section 3.3 in RFC-6749. It states that if scope is empty, then we must either handle it with a default value or throw an error.

And here’s the interesting part. I propose two solutions to the problem; I’ve implemented the first one in the current commit, and in the future we can pivot to the other solution. The first is to directly handle the case at the consent stage when scope and authorities are empty and allow the event to proceed. The second is to throw an error on a device_authorization request if scope is empty.

I think the first solution is better because it’s also easier to maintain. With the first solution, the test breaks, but that’s because it handles all cases and is abstract, so I refined it for the case where authorities is empty but scope is not empty. The second solution breaks the specific test case OAuth2DeviceAuthorizationRequestAuthenticationProviderTests#authenticateWhenNoScopesRequestedThenReturnDeviceCodeAndUserCode.

Closes: gh-19238
Ref: gh-19256

The main issue is inconsistent behavior. A `device_authorization`
request without a `scope` is always accepted, but then, during the
`consent` phase, if `authorities` is empty, we always get an
`access_denied` error. However, would not it make sense to continue
processing when both `scope` and `authorities` are empty?

The `scope` parameter itself is optional according to
[RFC-8628](https://datatracker.ietf.org/doc/html/rfc8628#section-3.1).
There is also a note attached to it that refers to [Section 3.3 in
RFC-6749](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3). It
states that if `scope` is empty, then we must either handle it with a
default value or throw an error.

Closes: spring-projectsgh-19238
Ref: spring-projectsgh-19256

Signed-off-by: Andrey Litvitski <andrey1010102008@gmail.com>
@therepanic therepanic changed the title Handle empty authorities in device authorization consent Fix device authorization flow without requested scopes Jun 2, 2026
@therepanic

Copy link
Copy Markdown
Contributor Author

I renamed the PR to avoid being tied to the commit title in case we decide to change direction.

Comment on lines +207 to +209
if (!authorities.isEmpty()) {
OAuth2AuthorizationConsent authorizationConsent = authorizationConsentBuilder.build();
if (currentAuthorizationConsent == null || !authorizationConsent.equals(currentAuthorizationConsent)) {

@therepanic therepanic Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If left unprocessed, the following OAuth2AuthorizationConsent.Builder#build assertiong will be executed

public OAuth2AuthorizationConsent build() {
    Assert.notEmpty(this.authorities, "authorities cannot be empty");
    return new OAuth2AuthorizationConsent(this.registeredClientId, this.principalName, this.authorities);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: waiting-for-triage An issue we've not yet triaged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth2 Device Code Flow requires to be used with a requested scope

2 participants