spring-projects / spring-security

Spring Security
http://spring.io/projects/spring-security
Apache License 2.0
8.86k stars 5.91k forks source link

Support JWT as an Authorization Grant for client #6053

Closed jgrandja closed 3 years ago

jgrandja commented 6 years ago

This feature will partially implement JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants.

Section 2.1. Using JWTs as Authorization Grants will be the focus for this feature implementation.

JWT Bearer Token can be used to request an access token when a client wishes to utilize an existing trust relationship, expressed through the semantics of the JWT, without a direct user-approval step at the authorization server

One of the primary use cases for using a JWT as an authorization grant is to exchange it for another JWT (at the Token Endpoint) with narrowed scope. This is useful when a service (a) wants to call another downstream service (b) with onlyscope that service (b) understands (supports).

NOTE: This ticket addresses client-side support only.

Related #5199 #8175

gandrade commented 5 years ago

Would be great have this feature targeting next milestone.

jgrandja commented 5 years ago

@gandrade We've been working hard on the upcoming 5.2.0 release (scheduled Sep 19), and it's looking like I won't be able to get to this feature in time. There have been quite a few other priority items that I've been working on.

It would likely be faster if someone from the community can provide a PR for this feature. Although this is not a trivial feature to implement, it would have a very similar implementation as #7013.

Would you be interested in submitting a PR for this feature? If not, I'll leave this up for someone in the community to pick up.

ThomasVitale commented 5 years ago

Hi @jgrandja, if someone was available to support me in clarifying and reviewing the technical design for this feature, then I would like to work on it. I am already familiar with the OAuth 2.0 specs and work daily on security features for enterprise applications. But since it would be my first feature-size task on this project, I could use some guidance.

jgrandja commented 5 years ago

@ThomasVitale Thanks for the offer! I actually have a POC in this sample.

However, I think it would still be valuable to review the spec and the POC code to determine if there is any other work left to do. I believe it's pretty close to being done but there may be other work that needs to be completed.

Let me know what you think?

matt-domsch-sp commented 5 years ago

FYI, the OpenID Foundation Fast Federation Working Group is defining a standard that will require RFC 7523 support. Lack of this in Spring will slow development and adoption of this emerging standard. https://bitbucket.org/openid/fastfed/src/master/text_spec/FastFed-1.0-Draft-01.txt

jgrandja commented 5 years ago

Thanks for the info @matt-domsch-sp. Would you happen to know which providers currently support RFC 7523?

matt-domsch-sp commented 5 years ago

I'm aware of these uses in the wild:

Other participants in the FastFed WG include SailPoint, Microsoft, Google, AWS, Yahoo, ADP, Ping, Okta, so I would expect broader adoption through 2020 and 2021.

jason-leagueapps commented 5 years ago

I actually have a POC in this sample.

However, I think it would still be valuable to review the spec and the POC code to determine if there is any other work left to do. I believe it's pretty close to being done but there may be other work that needs to be completed.

@jgrandja Is my interpretation correct that this POC code only applies to the client side and there isn't any work on the authorization server token endpoint side? Is this ticket meant only for client support?

TIA!

jgrandja commented 5 years ago

@jason-leagueapps Yes, you are correct. This ticket addresses the client support only. I've updated the subject of this ticket to be more clear.

mjeffrey commented 4 years ago

Keycloak also supports this with either a fixed certificate or a JWK callback. https://github.com/keycloak/keycloak/pull/4835 Keycloak and in particular the author of this PR have been doing a lot of work to support FAPI standards (needed by a lot of fintechs)

H-LREB commented 3 years ago

Hi, I have been using the classes from @jgrandja POC for a while and it works well. I submitted a PR to help integrate those classes into Spring Security.

jgrandja commented 3 years ago

@H-LREB Thank you for submitting the PR that integrates the code from the sample.

I'm pretty back logged these days and I wasn't planning on getting this feature in for 5.5.0.

There are a few priority items that I'm working on and given that 5.5.0-RC1 is scheduled for April 12, this will be very tight to get this feature in.

Having said that, the PR you submitted helps a lot. The other thing that would help a lot is to confirm that the implementation works for at least 3 well-known providers. This will give me a level of confidence to allow the merge. This is a crucial and necessary next step. Would you be able to help with this?

Either way, I will do my best to get this in for 5.5.0 but I can't promise at the moment. My next priority is #8175, which I'll be starting next week.

H-LREB commented 3 years ago

@jgrandja Thank you for your fast reply.

I totally understand that you guys have a lot to do and that the feature may not be ready in time for 5.5.0.

Yes, I would love to help with the tests of the feature. Which OAuth2 providers you usually use? I can follow the same steps. Do you have an existing setup that you already used to validate the implementation of the other grant types?

jgrandja commented 3 years ago

@H-LREB

Which OAuth2 providers you usually use?

I usually test with Keycloak, Okta and Curity. I think all 3 support jwt-bearer grant? You'll have to confirm if they do by looking at their reference doc.

We should also ensure it works with Microsoft Azure. See OAuth 2.0 On-Behalf-Of flow

H-LREB commented 3 years ago

I found the confirmation that Curity supports the jwt-bearer grant type. See "Assertion Flow" section in this document.

I could not find the same confirmation for Okta and KeyCloak. It does not seem they support this grant type.

As for Microsoft Azure, based on the request contents, I think we should be looking at the scenario "First case : Access token request with a shared secret". However, the Azure documentation describes a required parameter (in the request) which I do not see in the specification : requested_token_use.

May be it is worth mentioning that Okta seems to support the "Section 2.2 Using JWTs for client authentication" of the specification, according to this documentation.

I'll try to find more information

H-LREB commented 3 years ago

I tested the implementation with Curity and it works.

However, I still cannot find any mention of the jwt-bearer grant type in Okta or KeyCloak documentation. I don't think those providers support this grant type.

As for Azure, I'll try to find time to test it in the coming week, but I can't promise.

If someone new to Curity, like myself, tries to test the implementation against this provider, they shouldn't be intimidated by the error message "_invalidgrant". It does not mean the grant type urn:ietf:params:oauth:grant-type:jwt-bearer is not supported. Most likely, the error is because the jwt token in the assertion does not suit all the requirements described in Curity documentation.

mjeffrey commented 3 years ago

Keycloak docs are here and it does support this grant type.

https://wjw465150.gitbooks.io/keycloak-documentation/content/server_admin/topics/clients/oidc/confidential.html

On the server they support two possibilities

  1. Upload a certificate
  2. configure a jwks endpoint.

For the client (which you are interested in) they use this urn:ietf:params:oauth:client-assertion-type:jwt-bearer.

Keycloak provides their own spring-boot client (open source) which uses this the private_jwt auth mechanism. The code is in: AuthUtil.getAuthTokensByJWT() but it only supports the auth code grant.

p.s. It would be nice if spring security supported the client credentials grant with JWT and not just the auth code grant. 😄

H-LREB commented 3 years ago

@mjeffrey Thank you for this information,

However, I think you are referring to a different grant type. You are referring to the grant type urn:ietf:params:oauth:client-assertion-type:jwt-bearer whereas, in the current issue, we are looking at urn:ietf:params:oauth:grant-type:jwt-bearer (linked to Section 2.1. Using JWTs as Authorization Grants).

If I understood correctly, the grant type urn:ietf:params:oauth:client-assertion-type:jwt-bearer is linked to Section 2.2. Using JWTs for Client Authentication, which is the subject of gh-8175.

mjeffrey commented 3 years ago

@H-LREB Yes indeed. FYI I just searched the keycloak source code (server and client) for jwt-bearer and there is only the assertion so urn:ietf:params:oauth:grant-type:jwt-bearer may not be supported?

Thanks for the info on gh-8175 - that is the one I'm interested in 😄 .