spring-projects / spring-authorization-server

Spring Authorization Server
https://spring.io/projects/spring-authorization-server
Apache License 2.0
4.87k stars 1.29k forks source link

Token exchange failed when the subject token is a client_credentials granted access token #1691

Closed wapkch closed 2 months ago

wapkch commented 2 months ago

Describe the bug Token exchange failed when the subject token is a client_credentials granted access token.

To Reproduce

  1. build a spring authorization server which enables client_credentials grant for 'user-client' and token-exchange grant for 'messaging-client'
    spring:
    security:
    oauth2:
      authorizationserver:
        client:
          test-client:
            registration:
              client-id: "user-client"
              client-secret: "{noop}user"
              client-authentication-methods:
                - client_secret_basic
              authorization-grant-types:
                - client_credentials
              scopes:
                - user.read
          token-client:
            registration:
              client-id: "messaging-client"
              client-secret: "{noop}messaging"
              client-authentication-methods:
                - client_secret_basic
              authorization-grant-types:
                - urn:ietf:params:oauth:grant-type:token-exchange
              scopes:
                - message.read
  2. get access token for 'user-client' using client_credentials grant
  3. build resource server 'user-service' and 'messaging-service', user-service remote calls messaging-service
  4. Access resource server 'user-service' with the access token above
  5. token exchange failed due to the client_credentials granted access token does not have a 'princial' attribute, but OAuth2TokenExchangeAuthenticationProvider require a principal to be available via the subject_token for impersonation or delegation use cases:
image

Expected behavior As per https://datatracker.ietf.org/doc/html/rfc8693,there doesn't appear to be any explicit prohibition against using an access token obtained through the client_credentials grant for token exchange.

jgrandja commented 2 months ago

@wapkch

As per https://datatracker.ietf.org/doc/html/rfc8693,there doesn't appear to be any explicit prohibition against using an access token obtained through the client_credentials grant for token exchange.

This is true but at the same time the spec does not make any reference to the client_credentials grant type either.

Furthermore, looking at the examples in Appendix A. Additional Token Exchange Examples, you will see the subject tokens referenced contain "sub":"bdc@example.net" and "sub":"user@example.net" that clearly indicate a user principal.

As well, in 1.1. Delegation vs. Impersonation Semantics, it states:

One common use case for an STS (as alluded to in the previous section) is to allow a resource server A to make calls to a backend service C on behalf of the requesting user B

The word "user" is referenced in many parts in the spec, which implies there is a Resource Owner principal associated to the subject token.

I'm curious, why are you using a client_credentials obtained access token to represent the subject token in the token_exchange grant? If the client needs another scope, (message.read as per your example) why wouldn't the messaging-client be configured for the client_credentials grant and obtain a new access token with the required scope?

wapkch commented 2 months ago

@jgrandja That makes a lot of sense! Thanks for the detailed explanation. You can close this now.