I am using Authorisation Code Flow in my web application. I would like to get a refresh token for the web app itself but also an offline token that I will save in the database so I can use it later on for an offline task.
However I am struggling with that. I cannot use grant-type password because I don’t want to ask the user again to enter his/her credentials and also authorisation code is only one-time use so I cannot integrate it with the current flow.
Is there any other way to generate an offline token from a different token? I have tried using grant type refresh-token with scope offline_access but that didn’t work.
After keep working with Keycloak for several months, the answer is simple: it is not possible.
Offline token is effectively a refresh token with no expiration time so you can get one or the other but never both as part of the same request/response.
From a user point of view, we created a new page to request this token using password grant-type and offline scope. User need to re-enter his password but it seems ok from a security point of view. This approach works for us given the requirements to get this token as it is an unusual task.
You can also generate offline tokens using service account, check keycloak documentation on service account.
Following discussion will help you to understand different scenarios generating and using offline tokens
Related
I'm following this article to understand refesh tokens.
In my case I have to connect to REST api using grant_type=password, and I receive a token with a 5 minute lifespan. So every 5 minutes I have to issue a POST request passing client-id, username & password to get a new acces token.
The other option would be to issue a POST with a grant_type=refresh_token, without having to send the username & password. In my case I'm consuming an api, so passing the credentials doesn't involve any action from the final user. For me it's just to params more to send on the POST request.
In both cases, I have to issue a new post every 5 minutes.
Is that the only advantage (not needing to pass credentials again) of using the reresh token or is there any other thing I'm missing?
Background info
OAuth 2.0 Password Grant
The Password grant type is a way to exchange a user's credentials for an access token. Because the client application has to collect the user's password and send it to the authorization server, it is not recommended that this grant be used at all anymore.
OAuth 2.0 Refresh Token
The Refresh Token grant type is used by clients to exchange a refresh token for an access token when the access token has expired.
This allows clients to continue to have a valid access token without further interaction with the user.
Consider this.
Lets say that i add my login and password for my twitter account to your application and you then use that to request access from twitter to may account to post. Three months later i have forgotten i have set your awesome app up to do something on my twitter account and i change my password. Your system will break.
Now lets say i used Oauth2 to grant you access to my Google drive account, your awesome app can now do what ever it needs to do on my drive account. Now three months latter i have again forgotten i gave your awesome app access, I have the memory of a gold fish you see. I change my password. Nothing happens your awesome app still has access.
Now consider this, With oauth2 i can grant you access to only read from my google drive account not update it (scope). That and the system knows its not actually me preforming the actions.
With client login (login and password) most of the time it appears to the system that it is the actually owner of the account making the requests. You can also not limit access with client login for the most part you have full access.
note
yes i am ignoring the part about both tokens returned being the expiration time time. Thats because for all intensive purposes they are the same but that depends greatly on how the auth server you are using is set up. They could be set up to only be valid for an hour or a day. They may give you different access scopes, again this differs greatly from auth server to auth server.
I've been reading abount using Passport for the authentication process in a MEAN stack web app. I've been following this tutorial, but I got confused when it comes to the refresh tokens.
I do understand that those tokens are used to get a new access token for the user once it has expired, as explained here and in any other OAuth tutorial about thos tokens, but what I don't understand is how the server knows which refresh token must be used if the user hasn't provide any credential (it is supposed to provide the credentials just the first time is logging in).
Can anyone help me with this to fully understand how this works?
Thanks a lot :)
The Authorization Server issues the first refresh token after the user has authenticated. It then stores the association between refresh token and user as part of server side state so that it knows which refresh token was issued, whether it is still valid and for which user.
When the Client comes back to the Authorization Server with the refresh token later, the server can lookup the context and associated user from the server side storage.
Well, finally it turned out that the tutorial I was following was wrong (at least on what it comes to the refresh tokens).
On the tutorial it said that Passport use the refresh tokens to send a request to the Auth Server to get a new access tokens. Well, that's not true. According to Jared Hanson, the author of Passport, Passport doesn't handle refresh tokens, that's something the backend of the applications have to handle if desired. Passport is just meant to make the first request to the Auth Server, when you get the access and refresh tokens. Then you can use refresh tokens to request new access tokens, for example using background tasks to check if any access token is going to expire anytime soon.
I think the one who wrote that tutorial was confused cause the second time you login with whatever strategy is available (Facebook, for example), the service doesn't ask for credentials, but that's not because of the refresh tokens, that's just cause the browser is saving the FB session. If you go to FB and logout, the next time you try to login in the app with FB, it will ask again for the credentials. In fact, if I'm not wrong, access and refresh tokens should be removed once a user logs out. Kind of surprising that you could find that kind of mistakes in a IBM developers blog.
BTW, Jared Hanson's comment about how Passport works (without using refresh tokens) can be found here. Since is an old issue, I asked him myself on Twitter and the answer was just the same :)
Goal
Fetch a company's updates save them locally in a background task
Problem
This should be done as a backend service without any real user interaction. We could provide a user account to use, but the authentication is a problem: There is literally no one to answer the OAuth redirect and there is no public redirect URL to configure, since it's a background service.
Is there any way to access the API without having a redirect URL or a real user?
You can get an initial access token in a regular front end flow, for you as the app developer i.e yourself as the LinkedIn user. Once you've got that, you can store it in the backend and use it for 60 days to get access to the LinkedIn APIs.
After 60 days you need to refresh the token as documented in:
https://developer.linkedin.com/documents/handling-errors-invalid-tokens
Unfortunately LinkedIn does not (yet) support an autonomous refresh flow where your app can get a new access token by presenting a refresh token on a backchannel. So the developer will have to refresh the access token by a manual login every 2 months.
Well, it is still all HTTP and HTML, so in fact there is no real reason to show the OAuth dialog to a user, as long you can strip out the necessary parts in the HTML authentication dialog and send a valid response back to the server, using the username and password from the user (which you can obtain from him, or save it yourself in a config file if it is you).
Note that there might be a legal issue if LinkedIn demands you to actually show the dialog, beside that, there is no technical need.
I need to interact with an API that only supports OAuth2.
The problem is, I would like to write a purely server side application which should sit there without a GUI polling an API every day.
The API gives me the ability to get the application token programatically, but it looks like I need to implement the entire GUI flow to get the subsequent access token. This is because I need to log in via the application providers web based login screen.
It looks like I then need to get that access token, and copy this out as my server side credential where I recreate it. If that ever expires or goes bad, I'll need to go back via the GUI flow to get my server side access token.
Is my understanding correct here as this feels very clunky?
Specifically:
Can I avoid implementing the process where we link over to the application providers login form?
Is it right that after doing this, I have to unpick an access token and store this within my server side application. I don't appear to have any control over whether that will expire?
I can see that e.g. Facebook specifically support server side and client side flow. I wonder if I'm coming up against limitations in this particular implementation of OAuth 2?
I don't know how you actually want the app to behave, but one thing is certain - you do have to input the user credentials once.
Once you authenticate and authorize (there are a lot of open questions on SO, about automatic authentication), your app will get not only an access token, but also a Refresh Token. A refresh token is just what you need in your use case. You can store it your the server side - A refresh token does not have an expiration time. It lives till the user explicitly revokes permissions.
For any OAuth service provider there is a token exchange endpoint where you can exchange the refresh token for a (refresh token + access token) pair. So, at the backend (your server) you can at any time hit this endpoint - get a short-lived access token and perform the operation that you need to. This saves you all the effort of following the GUI flow every time.
See this link - https://developers.google.com/accounts/docs/OAuth2WebServer#offline
EDIT - Made some changes after reading your comment. You simply need to know how to use refresh tokens in your app.
I've found that the typical solution to the problem I asked in this question is to use XAuth.
Many providers such as Twitter and the application I am currently working against support XAuth to provide a simplified flow without the user interface based authentication.
What is the difference among BasicAuth,OAuth and XAuth?
I'm trying to add authentication feature to my application.
The authentication server implements oauth 2.0
I'm not sure how to save the refresh_token. I want to save it to a file, so next time when the application starts and there is a refresh_token available, it can ask for a new access_token. The user won't need to re-login again.
But this doesn't sound secure to me, because if someone copies my file that has the refresh_token to another computer, he can hack into my account.
You are correct with the attack that you describe. Refresh tokens have to be stored securely in order to be used as intended. As I understand, you are building a standalone application. Therefore, you can rely on file system security to prevent a refresh token being copied by an unauthorized user. You may want to use encryption for the refresh token, too, but the key would need to be bound to a user's session at your local machine (otherwise, the user would need to provide it during "sign in" process in order for the application to decrypt the refresh token).
Consider reading the thread from the OAuth WG, that discusses similar problems to the one described and provides some guidance:
https://www.ietf.org/mail-archive/web/oauth/current/msg02292.html
Refresh tokens are used to obtain access (this process requires HTTP Basic Auth). So, unless user has your (id,secret) combination he can't do much about it. However, storage of refresh token must be considered very seriously.
Here's my two cents:
Store your tokens in a DB
Whenever you use refresh token to obtain access token reset the refresh token as well. (Oauth2.0 has this feature, you can let the refresh token unchanged too, but it's wise in terms of security perspective to keep it changing and updating the DB)
Hope this gives some insights!!
You are right about your concern - you should not save the refresh token. By doing so, you jeopardize your client's data (and you know the reason; you wrote it in the question).
oAuth is not supposed to work this way.
You should keep the refresh token in-memory.