Refresh token not coming with authorize endpoint in oauth2 - spring

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.

Related

Should I or shouldn't I use refresh tokens with Password Grant authorization in Laravel Passport?

If I have a single page web application with a Laravel back end, my best option for authentication seems to be Passport with a Password Grant authentication flow. In Passport, this returns an access token and a refresh token.
For security, I would like to issue a short lived access token and refresh it when it expires. However, all the available information about using OAuth with a Javascript application says "don't make your refresh token accessible to the front end" because it's long-lived and can be used by others to generate new access tokens.
For example:
A Single-Page Application (normally implementing Implicit Flow) should
not ever receive a Refresh Token. A Refresh Token is essentially a
user credential that allows a user to remain authenticated
indefinitely. This sensitive information should be stored securely and
not exposed client-side in a browser.
Does this mean that a browser-based SPA cannot use refresh tokens and must, therefore, only issue access tokens that expire after a reasonable "session" length, forcing the user to log in again afterwards?
Otherwise, is there a suitable way to implement short-lifespan access tokens and refresh tokens in a Laravel Passport app with Password Grant authentication, while maintaining good security?
There is no harm in storing refresh token, as they can be used to get another access token after the access token(short lived as you mentioned) expires which create a good user experience.

Storing Bearer Tokens

I have successfully managed to create registration and login API routes in Laravel where a bearer token is issued when the user successfully logs in. The user may then use said bearer token to access his/her information and logout and so the user and logout routes are protected by authorization header middleware. For now I have tested these APIs using postman. For the actual implementation, when a user successfully logs in - where should the bearer token be stored (cookies perhaps?) in order for the user's session to pass the bearer token and access other pages with his/her information? Moreover how could a remember me method be implemented? and should refresh tokens be implemented? In order to eliminate cases where the user is logged out during a session if the token expires.
Tia!!
Yes, you have to implement refresh tokens.
And yes it's good option to use the cookie for storing the token and the date of expirations. Once it's expired you have to call the refresh token endpoint and to update the token in the cookie.
About 'remember me' method. As long as you are not cleaning the cookie when the user leave the page you are kind of implementing this method and it will keep the user logged in untile the refresh token is no longer available.

Spring Security OAuth 2: How to use access token in the javascript client

I have three applications: REST API with Resource Server, Authorization Server and javascript client on VueJs that should use REST Api. Problem in using access token that I get after authorization. First I decided to use local storage or cookie for storing access token, but as I read It's not secure. It's recommended to use cookie with httpOnly, but I can't to access from js. Addition token in url params as well not right way. So what I should to do for using my Rest Api? I'm using Authorization Code grant flow.
When you have a Javascript client, the client itself should act as an OAuth2 client.
Meaning, the server is not what gets the token. The client, the javascript application in the browser, will fetch the token from the authorization server.
You achieve this by using a grant type called implicit.
In this grant type, there is no client_secret, but you must have a valid client_id. You will also not receive a refresh token. But you can receive access tokens and id_token (if you have an OIDC server).
Your question hints at you doing a server side grant (authorization_code,password,etc) and then sending that token to the javascript client. This would be incorrect.
For a great description of OAuth2, we have published this video: https://www.youtube.com/watch?v=u4BHKcZ2rxk
Your JavaScript application would do this:
Do I have a valid token? No
Start implicit grant
Receive token from authorization server
Store token in memory var token = ....
Use the token to invoke API endpoints on the server
Repeat step 5 until token is no longer valid
Go back to step 1
Next step for you is to watch the video and learn more about implicit grant type
As you already guessed, going down the road of getting a token on the server and then sending it to a non secure client exposes your applications in ways you probably do not want.

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.

OneDrive App Access Token

Does anyone know how to get the app access token to a One-Drive API app?
I've tried combining {appId}|{appSecret} as the access_token param and as the Authorization header but it doesn't seem to work.
Thanks,
The OneDrive API docs have a good section on getting auth tokens with OAuth. In a nutshell, there are two services involved -- the OneDrive API service and the authentication service. The OneDrive API only accepts OAuth tokens that were issued by the authentication service. The authentication service is what you talk to first to get an auth token.
Depending on your app, you can either use the token flow or the code flow to get an auth token. In the 'token' flow, you navigate the user's browser to the authentication endpoint with your appId. The user may need to log in, consent, etc., and then the authentication endpoint redirects back to your site with an auth token you can use. The 'code' flow is similar to the 'token' flow, except it redirects back with an authentication code that your client app can use (along with its client secret) to obtain an auth token and a refresh token. Once you have a refresh token, you can use that to obtain future auth tokens without the user's involvement (as long as they granted the wl.offline_access scope).

Resources