Oauth refresh token grant types - spring-boot

I am learning Oauth grant types.I have observed that refresh token is applicable only for
authorization Code and Resource Owner Password Credential Grant .
My question is why it is applicable only for authorization Code and Resource Owner Password Credential Grant and not for Implicit and client credentials Grant?

Refresh tokens should only be issued to clients that can authenticate themselves when using it.
The authorization code grant is intended to be used by confidential clients (client that can keep a secret). And the use of the refresh token should be authenticated using client credentials.
The resource owner password credentials flow issues a refresh token, so that the client does not have to keep the user's username and password around. It can use the refresh token to get a new access token.
The implicit grant was intended to be used by public clients (who cannot keep a secret). Since they cannot keep a secret, there's no way for these clients to have client credentials used with the refresh grant.
And finally, the client credential flow does not need a refresh token, as it can just use the client credentials to get a new access token when the old one expired.

if you are using v5 you can use https://docs.spring.io/spring/docs/5.0.0.M5_to_5.0.0.RC1/Spring%20Framework%205.0.0.RC1/org/springframework/web/cors/CorsConfiguration.html
CorsConfiguration#applyPermitDefaultValues
or you can use
#RestController
#CrossOrigin(origins = "*", methods= {RequestMethod.GET,RequestMethod.POST})
public class HelloRESTController {

Related

Refresh token not coming with authorize endpoint in oauth2

I am trying to get refresh token when authorizing the user.
This is the url that is being used for authorization.
request
https://...../oauth2/authorize?response_type=token&client_id=test-client&scope=all&redirect_uri=https%3A%2F%2Flocalhost:7002%2F...%2Foauth
redirect url with token and etc :
https://localhost:7002/..../oauth#access_token=b3961289-713c-41c9-9341-253286cbcc52&token_type=bearer&expires_in=300&scope=all
but there isn't any refresh token with this. I tried this with token endpont and it has the refresh token like this
request
curl --data 'grant_type=password&username=....&password=...' --basic --user 'test-client:client-secret' 'https://....../oauth2/token'
response
{
"scope":"all",
"access_token":"5a90edb7-5ded-451a-9d9b-d3bd879ac336",
"token_type":"bearer",
"expires_in":300,
"refresh_token":"ec0c94db-5e81-4229-a815-9c2d80086995"
}
Is there anyway that I can get refresh token in authorization endpoint. ? Or
can I use existing token to get refresh token ?
This got to long for a comment
It kind of depends upon the authentication server how it works. Some servers only return a refresh token the first time the user authenticates.
To get a Refresh Token, you must include the offline_access scope when you initiate an authentication request through the authorize endpoint.
For example, if you are using Authorization Code Grant, the authentication request would look like the following:
https://__AUTH0_NAMESPACE__/authorize?
audience={API_AUDIENCE}&
scope=offline_access&
response_type=code&
client_id=__AUTH0_CLIENT_ID__&
redirect_uri=__AUTH0_CALLBACK__&
state={OPAQUE_VALUE}
This is the only way to obtain a refresh token so no you cant use another token to request get a refresh token.
Implicit client
In the implicit grant flow, the client is requesting access to a resource by way of a "User Agent", aka browser with the user sitting there. So a client wants to grab something, but needs the user to enter permissions for it. If the authentication server provided a refresh token, then the client could skip asking the user for permission in the future and grant itself access forever (essentially refreshing its token whenever it wants without user permission). This is forbidden in the flow because the "untrusted" client should only have access by way of having the user enter their credentials (thus only when the resource owner allows it).
You can't get a refresh token when using the Implicit grant.
I presume your application is a Single Page App? i.e. html/JavaScript running in a user's browser. This is the main use case for the Implicit grant nowadays.
If it's not a SPA (e.g. native, mobile or web application) you should be able to use a different grant type which will give you a refresh token. e.g. Authorisation Code Grant or Authorisation Code with PKCE Grant.

Is OAuth2 Password grant type and client_credential grant types the same?

As I understand before messing with Laravel Passport, password grant type is resource owner type and client_credential is for first party app, so basically routes protected with client_credential can access with token issues by itself,
My problem is token issued from password grant type can access routes protected by client_credential, and routes protected by api:auth can't be access by client_credential token
These are two different flow types.
First you need to understand the different between client and resource owner. This is explained clearly on roles section of the protocol.
resource server
The server hosting the protected resources, capable of accepting and
responding to protected resource requests using access tokens.
client
An application making protected resource requests on behalf of the
resource owner and with its authorization.
Now, the flows you have mentioned use credentials from resource owner and client. The clients in client credential flow are confidential clients. That means they have a client secret with them.
In resource owner password grant, you obtain tokens from token endpoint by presenting resource owner credentials. For client credential grant type, you obtain tokens from token endpoint by presenting client credentials. So as you can see they are two different flows.
Depending on the implementation, tokens issued for these flows could have different scopes. That mean, those tokens may have a different validity or could have limitations. Such restrictions are independent of OAuth 2.0 protocol.

Laravel API Passport Token

I have a question about laravel passport... I did the code and it is working very good, my question is about the token.
My friend has an mobile app which it will connect to my Laravel API... I already gave him a grant token my question is, do I have to give him a new token everytime that he wants to connect to the API? or just with that one is enough? one token and it works everytime?
I think that it works like this:
He wants to connect.
He passes the token to access to the API.
The API creates a response.
Am I correct?
For mobile application you should use password grant for Api protection. For password grant, the general concept is the API will give the app client the following parameters for accessing the auth client to get an access token and refresh token.
grant_type: password
client_id
client_secret
When the user login in the mobile application, the mobile app will use the above parameters and also the user's username and password to request a user specific access token, this token usually will be active for 60 minutes, after 60 minutes, the app client need to use the refresh token to get a new access token.
After getting the user access token, for the rest of your APP's api, the mobile client need to use this access token to access them.
For Laravel Passport, you can check out the password grant document here:
https://laravel.com/docs/5.4/passport#creating-a-password-grant-client
To understand more about what password grant is check out this link:
https://www.oauth.com/oauth2-servers/access-tokens/password-grant/
Note: From what I understand from your description, the grant type you are using is Client Credential Grant, this type is best for using system to system API authentication.

What is the purpose of grant_type parameter in OAuth 2 Authentication

I am using OAuth 2 Authentication in Lumen microframework. Right now i am using the grant_type value is password. It throws unsupported_grant_type, If i am using something different. I want to know the purpose of using grant_type is password
The grant_type URL parameter is required by OAuth2 RFC for the /token endpoint, which exchanges a grant for real tokens. So the OAuth2 server knows what you are sending to it. You are using the Resource Owner Password Credentials Grant, so you must specify it with the value password.
From the OAuth2 RFC:
An authorization grant is a credential representing the resource
owner's authorization (to access its protected resources) used by the
client to obtain an access token.
The grant_type=password means that you are sending a username and a password to the /token endpoint. If you used the Authorization Code Grant flow, you could use the value authorization_code. But then you don't send the username+password pair, but a code received from the OAuth2 server after user authentication. The code is an arbitrary string - not human readable. It's nicely shown in the workflow diagrams in the RFC.
in OAuth 2.0, the term “grant type” refers to the way an application gets an access token. OAuth 2.0 defines several grant types, including the authorization code flow. OAuth 2.0 extensions can also define new grant types.

Client secret + refreshing the access token in spring oauth2

I am using spring boot for backend and Android device for frontend of my system.
Right now I am facing the challenge to use Spring-OAuth2 to secure my resource server.
I have some questions, which I want to discuss with you:
My knowledge + this tutorial are saying that I should use the OAuth2.0 "password" grant type for my mobile app to obtain an access token. The official spring tutorial for security gives an example how to obtain the access token using password grant type:
$ curl client:secret#localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd
And here comes my first question: Is there any possibility to obtain access token using the password grant type without sending the "client secret" ?
Since the client secret could be "reverse engineered" by decompiling the client app. The obtaining access token without secret should be somehow possible, because Facebook SDK for Android also does not need the client_secret in the mobile app.
I think here I have a little trouble understanding why the clientID + clientSecret needs to be included in the request above, because, since there are already username + password included, it should be possible to generate the access token, so does this brings a next level of security ? and does it implies the following (example): I am logged in as Filip in my Android client and I am sending the access token A with each request to the server. Then I log in as Filip into web client and I try to access the resource server from web client using the access token A, which is not possible because access token A was issued only for Android client ?
The next question is how can I refresh the obtained access token ?
I was trying to do so using the command below, but I got "Full authentication is required to access this resource." After I got the new refreshed token, can I use the refresh token to refresh my new access token again ?
curl -v --data "grant_type=refresh_token&client_id=acme&client_secret=acmesecret&refresh_token=REFRESH_TOKEN" http://localhost:9999/uaa/oauth/token
Thank you
The OAuth 2.0 spec allows for so-called public clients i.e. clients that don't authenticate themselves. So it is possible to use the Resource Owner Password Credentials grant with a public client, i.e. one that does not need to send a client secret. It does mean that the Authorization Server cannot assume anything about the client since a client_id is not a secret and there's no way to prevent a malicious client using this grant type or clients from impersonating each other. So using it in this way comes at the cost of reduced security although one may argue that in your case there's no way to use confidential clients anyhow, so there's no difference.
In general the Resource Owner Password Credentials grant is an anti-pattern for OAuth and only meant for migration purposes because it defeats most of the goals of OAuth in itself.
Access tokens are issued on a per-client basis.
You refresh token request seems OK but the Authorization Server may require basic authentication instead of providing the client_id/client_secret as post parameters, considering that you did the same for the original access token request.

Resources