Skip to content
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

Implement OAuth 2.0 Token Exchange #1525

Merged
merged 2 commits into from Feb 28, 2024

Conversation

sjohnr
Copy link
Member

@sjohnr sjohnr commented Jan 26, 2024

See blog post for an overview of this feature.

@sjohnr sjohnr added the type: enhancement A general enhancement label Jan 26, 2024
Copy link
Member Author

@sjohnr sjohnr left a comment

Choose a reason for hiding this comment

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

@jgrandja I've opened this as a draft to gather feedback about specific things in the AuthenticationProvider, and the AuthenticationConverter and Authentication are implemented as well. I wanted to get feedback at this point before I go much further to avoid any rework, as the rest of the implementation would build on what I have so far.

So far, you can make a valid token exchange request with a subject or subject+actor, get an access token in response, and see an authorization in the DB with attributes. The new/updated token claims have not been implemented yet.

You can ignore the rest of the PR for now as it's still very much work-in-progress and local testing.

@jgrandja jgrandja assigned jgrandja and sjohnr and unassigned jgrandja Jan 30, 2024
@sjohnr sjohnr force-pushed the gh-60-token-exchange branch 2 times, most recently from fc42ab5 to 39b1350 Compare February 6, 2024 21:38
@sjohnr sjohnr force-pushed the gh-60-token-exchange branch 3 times, most recently from 6759bc5 to c4f83ce Compare February 13, 2024 22:50
@sjohnr sjohnr marked this pull request as ready for review February 13, 2024 22:51
@sjohnr sjohnr force-pushed the gh-60-token-exchange branch 2 times, most recently from cf10fef to b065ee3 Compare February 28, 2024 16:44
@sjohnr sjohnr merged commit 2ec9329 into spring-projects:main Feb 28, 2024
2 checks passed
@sjohnr sjohnr deleted the gh-60-token-exchange branch February 28, 2024 17:40
@jgrandja jgrandja added this to the 1.3.0-M3 milestone Feb 28, 2024
@Milesy
Copy link

Milesy commented Mar 12, 2024

@sjohnr - Is it possible to get some very basic documentation so I can have an experiment with the new code locally until the release is ready?

thank you very much for the effort

@sjohnr
Copy link
Member Author

sjohnr commented Mar 13, 2024

@Milesy I plan to add documentation into RC1. In the meantime, you can clone this project and run the sample applications to see token exchange in action to learn how it works and inspect the code/configuration to learn how to configure it. Even after the reference documentation is in place, the demo-authorizationserver sample is still one of the best places to learn about supported features.

You simply need to add the grant type for the registered client. You can also take a look at a new token customizer specific to token-exchange. If you need to customize anything about the token beyond the basics, you can register a token customizer which gives access to the entire token request through OAuth2TokenExchangeAuthenticationToken.

@Milesy
Copy link

Milesy commented Mar 14, 2024

@sjohnr thank you - and apologies for questions here I am not sure where else I can add them given how new this stuff is. I have got everything configured but I am failing on:

static OAuth2ClientAuthenticationToken getAuthenticatedClientElseThrowInvalidClient(Authentication authentication) {
        OAuth2ClientAuthenticationToken clientPrincipal = null;
        if (OAuth2ClientAuthenticationToken.class.isAssignableFrom(authentication.getPrincipal().getClass())) {
            clientPrincipal = (OAuth2ClientAuthenticationToken)authentication.getPrincipal();
        }

        if (clientPrincipal != null && clientPrincipal.isAuthenticated()) {
            return clientPrincipal;
        } else {
            throw new OAuth2AuthenticationException("invalid_client");
        }
    }

I have configured the resource server with a JWT decoder, which is the authentication token used within our corporate network. But it means the class type is:

class org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken

And the method throws invalid_client back out of the request.

I must be missing some piece of the puzzle to how I create a OAuth2ClientAuthenticationToken with a registered client, and the underlying JWT principal

@Milesy
Copy link

Milesy commented Mar 15, 2024

@sjohnr - in my use case, the token the user has is not issued by this server. The problem I am trying to solve is where we have multiple IDPs coming into our gateway, and we want to exchange that token for a common generic token that can then be used internally. So both the Authorization: header and the subject_token is the same. It is not possible to use any sort of password or client secret based authentication.

@sjohnr
Copy link
Member Author

sjohnr commented Mar 15, 2024

@Milesy this issue tracker is not a support forum, so I would ask you to please direct specific questions about your implementation to Stack Overflow. Having said that, this token exchange implementation is not a general purpose Security Token Service (STS) and is not designed to exchange arbitrary tokens and furthermore does require client authentication, so the error you are receiving is expected.

sjohnr added a commit that referenced this pull request Mar 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

3 participants