spring-security icon indicating copy to clipboard operation
spring-security copied to clipboard

Implement JWT Authorization Grants

Open rlewczuk opened this issue 4 years ago • 16 comments

Implement JWT Authorization Grant as defined in RFC 7523.

rlewczuk avatar Dec 17 '21 18:12 rlewczuk

For those inquiring about the future of this feature, @jgrandja has confirmed it's scheduled for release 1.1.0

fkhantsi avatar Dec 30 '22 01:12 fkhantsi

@fkhantsi Correction. This feature is not scheduled as of yet. The link states:

We are also planning on documenting "Adding an extension authorization grant" in the reference manual via https://github.com/spring-projects/spring-authorization-server/issues/686. I scheduled it for the 1.1.0 release.

To clarify, spring-projects/spring-authorization-server#686 is scheduled for 1.1.0.

jgrandja avatar Jan 03 '23 17:01 jgrandja

is there any sample for using JWT Bearer? I noticed 1.1.0 had been released.

imwangyi avatar Jun 28 '23 04:06 imwangyi

Hi, Any plan in near future to implement this.

Thanks.

bhashitbhatt avatar Jun 11 '25 11:06 bhashitbhatt

@bhashitbhatt There are no plans as of yet.

We have a number of higher priority items on our list for the major release of Spring Security 7.0 and Spring Authorization Server 2.0 and with less resources on our team it will limit the new features in the next release.

jgrandja avatar Jun 11 '25 13:06 jgrandja

Thanks for the providing the update @jgrandja

bhashitbhatt avatar Jun 11 '25 14:06 bhashitbhatt

Hey @jgrandja we're likely to need this feature in the next quarter. It's worth noting that it's a requirement for some social logins like Google's Streamlined account linking https://developers.google.com/identity/account-linking/oauth-with-sign-in-linking if you need a motivating use-case for this to be implemented.

If you think it's unlikely that the Spring Security team will get to this before then, we'd be interested in contributing an implementation to SAS to ensure that we remain aligned with the core product. In that case it would probably good if I can outline roughly how I would propose to implement it here before I start to avoid wasting effort on an approach that doesn't fit with your design goals.

One awkwardness here is that in e.g. Google's usage of this grant type, a refresh token is returned. RFC 7523 says nothing one way or the other about this, but obviously doing so requires that the grant be stateful like an auth code grant, which I imagine would significantly complicate the implementation.

symposion avatar Oct 28 '25 09:10 symposion

@symposion

it would probably good if I can outline roughly how I would propose to implement it here before I start to avoid wasting effort on an approach that doesn't fit with your design goals

I agree. Let's discuss here before we go ahead with anything.

I believe the implementation would be very similar to OAuth2ClientCredentialsAuthenticationProvider. The one specific area that I'm most interested in is how the assertion parameter would be validated, considering in most use cases the assertion is minted from an external identity provider.

Google's usage of this grant type, a refresh token is returned. RFC 7523 says nothing one way or the other about this

Refresh tokens should not be returned. As per 4.1. Using Assertions as Authorization Grants:

An assertion used in this context is generally a short-lived representation of the authorization grant, and authorization servers SHOULD NOT issue access tokens with a lifetime that exceeds the validity period of the assertion by a significant period. In practice, that will usually mean that refresh tokens are not issued in response to assertion grant requests, and access tokens will be issued with a reasonably short lifetime. Clients can refresh an expired access token by requesting a new one using the same assertion, if it is still valid, or with a new assertion.

jgrandja avatar Nov 10 '25 15:11 jgrandja

Refresh tokens should not be returned.

Yeah, I was afraid you'd say this :-/ I agree with you, but unfortunately Google have taken a different view on this. They're using this grant as part of an account linking process, and because the JWT transmitted as part of it contains a limited amount of Personally Identifying Data, they only want to send it while the user is interactively engaged with the process; but they still want to be able to then use the linked account for offline access later on - thus the requirement for refresh tokens.

I completely understand that you probably don't want to build this in to the basic implementation - I agree that the intention of the spec is clear here, even if it does stop short of explicitly prohibiting the return of a refresh token (it only says "that will usually mean...."); but given that Google is Google and this is a pretty significant use case for this grant, I think it would be great if we can find a way to implement it that leaves open the possibility of returning a refresh token by some kind of relatively limited customisation. Not to put too fine a point on it, we absolutely have to have this functionality as a result of Google's choices here, so we will be implementing it in a way that permits this whatever happens. The only question is whether we can find a way to do it that lets us contribute our implementation back to the project, or if it has to be a completely bespoke implementation. I think it would be a shame if we ended up there, particularly as this is standard part of Google's IAM mechanisms, so I'm sure there will be others that need to do the same.

symposion avatar Nov 10 '25 16:11 symposion

I believe the implementation would be very similar to OAuth2ClientCredentialsAuthenticationProvider

One interesting problem/question here is that you can - and frequently will - have both an authenticated client and (sort of) an authenticated end user (as specified by the JWT assertion). I'm assuming that we will need to reserve the main security context for any possible client authentication (as happens for e.g. the client_credentials grant) and then handle the JWT assertion of the end user locally to the authentication provider for this specific grant.

However, the closest parallel that I can find for validating the JWT assertion would be Spring Security's implementation of OAuth2 login, which is very much tied to creating an interactive login session. I suspect that trying to leverage much of this - despite the close parallels - is likely to just result in more confusion and maintenance issues. Also potentially relevant is the IDP federation sample, which is dealing with some of the same problems (handling an external IDP assertion of identity).

It might be a bit ambitious but it would be fantastic if we could find a way to align the handling of all of these at least to some extent. The basic problem is more or less the same in each case:

  • External assertion of identity in the form of a JWT with some kind of identifiers
  • Process that assertion - possibly by looking up against an existing user store (e.g. OidcUserService)
  • Potentially handle on-the-fly local user creation if appropriate
  • Produce access token (and maybe other tokens) based on the resulting user (for JWT Auth Grant/Federated IDP) OR add them to the security context as the logged in user (for OAuth2 Login)

It's really the middle of that process that's common to all of these - translating an external JWT to a local user - and I think it would be a great outcome if we could find a way to achieve that without loads of code duplication/completely separate mechanisms

symposion avatar Nov 10 '25 16:11 symposion

@symposion The goal always is to provide a spec-compliant implementation and to provide customization hooks to allow for off-spec behaviour. We can do a spike and see if we can find a solution that fits the goal.

Would you be interested in submitting a draft PR that we can iterate on?

jgrandja avatar Nov 11 '25 21:11 jgrandja

Yep that sounds good. Due to scheduling constraints at this end it's likely to be in the New Year, but I'll keep you posted.

symposion avatar Nov 12 '25 07:11 symposion

Also related, but yet a different feature: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-identity-chaining-06 OAuth Identity and Authorization Chaining Across Domains:

This specification describes a combination of OAuth 2.0 Token Exchange [RFC8693] and JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants [RFC7523] to achieve identity and authorization chaining across domains.A client in trust domain A that needs to access a resource server in trust domain B requests a JWT authorization grant from the authorization server for trust domain A using a profile of OAuth 2.0 Token Exchange [RFC8693]. The client in trust domain A then presents the received grant as an assertion to the authorization server in trust domain B, using the JWT authorization grant feature of [RFC7523], to obtain an access token for the protected resource in trust domain B.

Finally, https://datatracker.ietf.org/doc/html/draft-ietf-oauth-identity-assertion-authz-grant-01 aims at fleshing out the details:

The draft specification Identity Chaining Across Trust Domains [I-D.ietf-oauth-identity-chaining] defines how to request a JWT authorization grant from an Authorization Server and exchange it for an Access Token at another Authorization Server in a different trust domain. ... This specification defines the additional details necessary to support interoperable implementations in enterprise scenarios when two applications are configured for single sign-on to the same enterprise identity provider.

A security vulnerability in rfc7523 has lead to this proposed fix in rfc7523bis: https://www.ietf.org/archive/id/draft-ietf-oauth-rfc7523bis-03.html#name-updates-to-rfc-7523

dschulten avatar Dec 07 '25 14:12 dschulten

@jgrandja would the SpringOne23 code be an acceptable starting point for a PR? https://github.com/sjohnr/spring-authorization-server/blob/springone-2023/samples/demo-authorizationserver/src/main/java/sample/authentication/JwtBearerGrantAuthenticationProvider.java

dschulten avatar Dec 07 '25 18:12 dschulten

@dschulten

would the SpringOne23 code be an acceptable starting point for a PR?

Possibly. We'll review it when we start the spike.

jgrandja avatar Dec 08 '25 15:12 jgrandja

This issue was transferred from spring-projects/spring-authorization-server (see spring-authorization-server#2195)

jgrandja avatar Dec 09 '25 19:12 jgrandja