I am implementing OAuth 2.0 in Laravel5 for one of my web services project to protect my api endpoints.
I am using password and refresh token grants.Everything is working fine, but I am wondering what if my refresh token is lost during its transaction from server to device, like if internet is disconnected and device doesn't get any refresh token so how it will generate a new access token to perform actions.
You would have to login again? (user credentials)
Related
There is API on Laravel, which uses Laravel Passport for authentication. All worked well with the default settings. Then we decided to change the lifetime of the access token to 1 day and 1 month accordingly. It caused a problem with the refresh token.
Example: Access token is expired and the app sends the refresh token request to API. Then the app loses internet connection and can't get a new token. (Server sends new tokens but the app is unavailable). After the internet connection returned, the app sends a new refresh request but get 401. So apps need to get new code from API to authenticate the user. I don't think it's a good idea to force the user to login every day.
Any suggestions? Maybe there is some way like "handshake" to solve that problem? I mean refresh token only after confirmation the app got new tokens.
If I correctly understand your question, you're saying that you initially have an Access Token1, Refresh Token1 pair, and when the Access Token1 expired you try to request a new Access Token using the Refresh Token1.
Now, for some reason, you fail to receive this new Access Token2, Refresh Token2 pair, so what does the user do?. Well, you see this from the Consumer's point of view. If you see the same scenario from the Oauth2 Server's point of view.
The Server does not know if you failed to receive the token or you received it and failed to save. The server's job was to generate a new access token based on your valid refresh token. And as soon as it creates a new access token, it invalidates the old refresh token. This is the standard Oauth2 implementation.
You may try to make it so that the Old refresh token is not immediately revoked on new access token generation. But this introduces a possibility of replay attacks.
Hence, The standard practice is to have the User log-in again.
We have a web app in which we allow users to log into the app using any Open ID provider(e.g. Okta, Google, Facebook etc.). We want to implement the correct Open ID Connect prescribed methodology/workflow to keep the user logged into the site.
The existing implementation, looks at the expiry of the Access Token then if it's close to expiry uses a Refresh Token to get a new Access Token to keep the user logged in. I feel like this is wrong. When a user logs in to the web app, the Identity Token is used to Authenticate the identity of the user using the Authorization Code workflow. The Access Token and Refresh Token are stored on the server side. Periodically, the Refresh Token is used to get new Access Tokens to keep the user logged into the site. I believe this is a security risk because -
Imagine if a user is logged onto his OP account in a browser. He opens up Sky and is directly logged into MP because he’s already logged into MP. He then in a separate tab, logs out of his OP account. He will continue to be logged into MP for days on the basis of this Refresh Token/Access Token mechanism! Isn’t this a security risk?
If feel like the correct way to go about this is to use Session Management using iframes as prescribed here on OIDC -
https://openid.net/specs/openid-connect-session-1_0.html
For more context, when a user logs into our WebApp we pull data from the OP's UserInfo endpoint to create a profile within our WebApp and set permissions/roles within our app based on data sent over from the OP's UserInfo endpoint. We continue doing this periodically. For this purpose, I feel like using the Access Token(and using the Refresh Token to get new Access Token) to access the UserInfo API is correct because it conforms to the OAuth 2.0 concept of protecting/authorizing API/Resource endpoints using Access Tokens.
I want to know if this is indeed the correct way to manage how a user should be logged in when supporting Open ID Connect.
I think the first question is whether you want to bind the lifetime of an OpenID Connect provider Single Sign On session with the session of your application. You just want to authenticate a user using their OpenID Connect service. If I logout of Google, I expect to be logged out of GMail, but not a third-party application that used Google for authentication. Would you like to implement Single Sign Out as well?
But if I wanted to be logged out when you logout of the OpenID Connect provider, I would implement the OpenID Connect Session management. There is one thing good to be aware of when using iframes and cookies - browsers have an option to "Block third-party cookies" (that's how Chrome calls it), it's turned off by default, but as far as I know, it disables the SSO functionality when turned on.
I'm not sure why you request the userinfo endpoint periodically. If you just want to check whether the access token is still valid, you could also use the token introspection endpoint.
For security concerns, I would suggest you to read the OAuth 2.0 for Browser-Based Apps RFC. It recommends using the auth code flow with PKCE instead of the implicit flow. With the implicit flow, access tokens transported in redirect URLs stay in network and browser caches and can be used right away by an attacker. The auth code with PKCE needs a code_verifier (one-time secret) in order to be exchanged for tokens. So I would first check how the providers work with a configuration you choose and if it's even supported.
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.
I have been following a tutorial to create a Spring SSO application which uses Facebook for authentication but creates its own access tokens to secure back-end resources.
The sample application creates a user on first login and stores the user's facebook token for further use (getting data from facebook later on).
My question is that how do I handle token expirations? When the facebook token expires, how do we setup spring security to refresh it? What about our application's token expiration?
You can find my sample project here.
The app in the tutorial only uses the token for authentication (i.e. it uses it once when the user logs in to get the user's personal details), so it's highly unlikely to expire in the time it is being used. Having said that, the OAuth2RestOperations instance that is used to carry out that single request is capable of refreshing the token on its own (if the provider sent it a refresh token and allows the access token to be refreshed by your client).
I can see OAuth working well for a fully Ajaxified application, as the local JS code can always replay the Bearer token to the server. However, what happens if we have a page refresh? In that case I assume we lose the token and then go back through the OAuth redirect process to get yet a new access token issued. Is this correct, and are there patterns to avoid this, such as storing the access token in HTML5 local storage?
If you're talking OAuth 2.0 then you can probably request both a refresh token and access (or Bearer) token when you authenticate with the OAuth 2.0 provider. The refresh token should be returned directly to the server hosting the web application, stored somehow (perhaps session state) and NOT ever exposed to the browser. The browser can use the access token to make requests to secured services/endpoints which require it but it should have a short lifetime (regardless of whether or not there was a page refresh). When it expires (again may or may not be due to a page refresh) the client application can make a request to the hosting server where the refresh token was delivered. The server can then use the refresh token to get a new access token WITHOUT the user needing to login again.
There's a diagram of this in the refresh token section of the OAuth 2.0 spec.
There are several variations of how OAuth 2.0 can be used and details may vary with your particular scenario and implementation but hopefully that gives you a high-level idea of how you can avoid prompting the user to re-authenticate when the access token expires or on page reload.