Can I use JwtBearerReactiveOAuth2AuthorizedClientProvider to implement Client Secret JWT Authentication? - spring-security

I do have an app that is using ReactiveOAuth2AuthorizedClientProvider in order to get a token using authorization-grant-type: client_credentials & client-authentication-method: post
I need to uplifted to support JWT using client-authentication-method: private_private_key_jwt
I have seen spring providing the JwtBearerReactiveOAuth2AuthorizedClientProvider & I'm wondering if I can use it.
I did not found any samples so far on google searches.

Related

How JWT is different from OAuth 2.0?

I have done a sample application using Sprint Boot, Spring security and JWT and define my custom authentication & authorization filters. While performing basic authentication (passing username & password) I get JWT token in the format of xxxx.yyyy.zzzz where xxxx is header, yyyy is payload and zzzz is signature and each part is encoded using Base64URL encoder. What I do not understand is how JWT is different from OAuth 2.0. In OAuth 2.0, we can pass 2 types of grant_types as either 'username' or 'client credentials' & also needs to pass client id, secret id to get access & refresh tokens.
Please assist to clarify my following doubts:-
1) Is JWT lighter than OAuth 2.0 as it does not contain the refresh token but just access token?
2) Is JWT cannot be used to make a standalone authorization server like we can make a standalone authorization server using #EnableAuthorizationServer annotation when it comes to OAuth 2.0. Is my assumption correct?
3) JWT does not accept client id/secret client but just used as basic authentication to get bearer tokens?
4) Is the format of access token (or bearer) for both OAuth2.0 and JWT are different?
I have seen an example where both OAuth 2.0 and JWT were used. OAuth 2.0 was to make authorization server which returns JWT token only in the end but did not understand why JWT was used if OAuth2.0 can return a token by itself.
Thank you
JWT is a JSON-based token defined in RFC 7519. OAuth 2.0 is an authorization framework defined in RFC 6749. Comparing both is like asking "How Glucose is different from Apple Pie?".
However, it is possible to bring OAuth 2.0 and JWTs together as is defined in RFC 7523 – The JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants. It standardizes, how to use JWTs as bearer tokens within the OAuth 2.0 framework, which enables what I call stateless authentication.
Regarding your questions:
Whether or not you use JWTs as bearer tokens does not influence whether or not you want to hand out refresh tokens.
Not sure whether I get your questions. However, using JWT allows you to do decentral, stateless auth decisions as there is no necessity to store token state centrally. However, nobody prevents you from having a standalone authorization server.
How you want to do authentication has nothing to do with JWT. It is still OAuth 2.0.
In OAuth 2.0 bearer tokens are considered to be opaque tokens – the format does not matter. If you use JWTs as bearer tokens, you need to follow the corresponding RFC.

Does OneLogin support client_credentials?

Having trouble finding the information in OneLogin regarding client_credentials.
I'm just looking to setup the flow for an API that we have.
A client app will request a token using client_id, client_secret, then use that token to access our API. Was hoping that OneLogin was a token provider, and could even assist in some way.
I've gotten as far as setting up a developer account, then creating an API, but I have been unable to obtain an access token from the API - and even if I did it seems to be a token I would use to access the other features in the OneLogin API.
Can anyone tell me if what I'm trying t achieve is possible with OneLogin?
Machine to Machine, or client to API communication.
Thanks in advance!
I'd recommend setting this up with OpenID connect:
https://developers.onelogin.com/openid-connect/api/password-grant
This will generate a token (and refresh token) that can be validated against OL.

How to validate the access_token generated by onelogin using API

If I can perform authentication using oAuth2 using onelogin, can I also validate the same token using REST API's instead of accessing the the onelogin resources ?
I ask this question because for Google we can validate it using JWK keys, and other tokens ca be validated by the server keys. If that is not possible then at-least we should be having some REST API that could validate the token when passed. Does onelogin support any of these use-cases ?
Check out our OIDC support (https://developers.onelogin.com/openid-connect) as this basically allows for Authenticating users via JWT/JWK tokens

To what extent do the Google OAuth 2.0 APIs support RFC7636?

I am looking for concrete information regarding the state of RFC7636 (proof key for OAuth token exchanges) in Google's OAuth2 APIs.
Google exposes an OAuth 2.0 and OIDC provider API where access tokens can be obtained. There is a proposed standard described in RFC7636 for using proof keys in token exchanges which we have started using in our integrations with major identity providers. Some accept the proof key, others ignore it; Google seems to be aware of it but fails to validate the proof key. I have not been able to find any mention of this wrt Google.
In concrete terms, when following the authorization code flow of OAuth 2.0 with Google as the provider we generate a random number, hash it using SHA256, base64 URL encode it, and then pass it to https://accounts.google.com/o/oauth2/v2/auth as parameter "code_challenge" and "code_challenge_method" as per the spec.
The endpoint accepts the parameters and issues an authorization token as usual. When obtaining the access token we call https://www.googleapis.com/oauth2/v4/token with the code_verifier; the endpoint returns the following HTTP 400 error which suggests that there is some awareness of code verifiers:
{
"error": "invalid_grant",
"error_description": "Missing code verifier."
}
Google's OAuth documentation at developers.google.com/identity/protocols/OAuth2 does not mention any of these parameters; the API playground does not extend to playing with the OAuth2 auth and token endpoints. Any insight would be greatly appreciated.
I was having this same problem using AppAuth and an Android clientId. In order to fix it I had to set a matching 'code_verifier' field on both the authorization and token requests. You can find a more in depth description in this post: invalid_grant trying to get oAuth token from google

How does 2-legged oauth work in OAuth 2.0?

In OAuth 1.0, 2-legged is pretty easily: Simply send the request as usual and omit the access_token header.
Things seems to have changed in OAuth 2.0 (drastically, as I found out today :)). In OAuth 2.0, the request no longer has headers such as the nonce, consumer key, timestamp etc. This is just replaced by:
Authorization: OAuth ya29.4fgasdfafasdfdsaf3waffghfhfgh
I understand how 3 legged authorizations work in OAuth 2.0 and the application flows. But how does 2-legged work in 2.0? Is it possible to design an API that can support both 2-legged and 3-legged OAuth 2.0?
I have been searching for information regarding this, but I have been finding a lot of stuff on 2-legged for 1.0 and almost nothing for 2.0.
After lots of research, I discovered that client_credentials grant type is for this scenario. Once you punch this term into google, you can find loads of very helpful resources.
This is the normal flow for 3-legged OAuth 2.0 (we want the user to sign in):
Assume we have the following endpoints in our app for authentication:
/oauth/auth
/oauth/token
Normally (for authorization code grant), we direct the user to /oauth/auth?state=blah&client_id=myid&redirecturl=mysite.com/blah
Then upon authentication, the user is redirected to mysite.com/blah?code=somecode
We then get somecode and exchange it for a token using /oauth/token?code=somecode&client_id=myid&client_secret=mysecret
We can then use the token to make calls.
This is the application flow for client_credentials to implement 2-legged OAuth 2.0, which is markedly simplier:
In this approach, we do not need to perform any authentication.
We simply POST to /oauth/token with the following form data:
grant_type=client_credentials&scope=view_friends
Note that scope is optional. The endpoint then directly returns an access token for us to use (no refresh token is provided). Since no refresh token is provided, when the token expires, you will need to reauthenticate and ask for a new one.
This leads to the following caveats:
Use this only for (very very) trusted applications such as internal applications.
You need to devise your own way to authenticate. For instance, the RFC's example uses basic auth.
Another solution is to use JWT (JSON web tokens) like the google OAuth API. It is a very complicated process, but there exists numerous libraries for generating your JWT. You then post the following form data (url encoded of course):
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=generated_jwt
This is posted to /oauth/token to get your token.
As for the question of whether you can create an API that supports 2-legged and 3-legged OAuth 2.0, Yes, it is possible.
Then /auth endpoint is only used when users need to authenticate against the service.
In the /token endpoint, simply check the value of grant_type in the GET parameters for urn:ietf:params:oauth:grant-type:jwt-bearer if using JWT or client_credentials for client_credentials.
Note that when generating the client_id and client_secret to give to the user, if you are supporting multiple grant_types, ensure that you have a database column to store what type of grant type the id and secret was generated for. If required to have multiple grant types per user, generate a different set of credentials for each grant type.
You can also check out Google's implementation of 2-legged OAuth2 (I believe this documentation has been published only recently).
The Google Drive SDK delegation docs should also help understanding Google's 2-legged OAuth2 implementation.

Resources