Using refresh tokens between sessions - javascript

I am implementing OAuth2 in my PHP web application. Access tokens are distributed to javascript web clients with an expiration of 1 hour, and a refresh token is provided. If the client quits the browser for more than 1 hour the next time they navigate to my web application the access token is no longer valid during the initial request to the resource server. The resource server then returns a unprotected page.
In the event I have:
Expired access token
Valid refresh token
New session
Should the resource server return a unprotected page, and the client using javascript attempt to refresh the access token and if successful force the page to reload? Is that common? Or am I missing something so the resource server isn't called twice?
Currently the client passes the refresh token to the resource server, so technically the resource server could refresh the access token. But, this doesn't seem to be allowed by RFC 6749 which seems to indicate the resource server should never see the refresh token.
"Refresh tokens MUST be kept confidential in transit and storage, and
shared only among the authorization server and the client to whom the
refresh tokens were issued."

In any case, as you indicate, one never passes a refresh token to the Resource Server. The refresh token is only ever presented to the Authorization Server. But:
In-browser clients such as Javascript clients should use the Implicit grant to get their access token. In that case there is no refresh token that is issued. That should not be a problem with in-browser clients since the user is present in that case, so no refresh token is needed to get a new access token: the user will just authenticate to the Authorization Server again, hopefully leveraging an existing SSO session for that.

Related

How are JWT refresh tokens meant to be sent from the client to the backend?

It is my understanding that, as someone that has recently started using JSON web tokens that, once an access token expires, a new one may be generated using a refresh token.
I currently have some middleware on my server configured such that, if a JWT verification fails, it uses the refresh token to generate a new access token and then attempts the verification process again. If this succeeds, it sends a response with the new access token attached. If it fails, it sends a 401 error.
For this to work, however, the client must send both the access and refresh tokens. My fetch requests are currently configured such that they send the access token under the Authorization header as Bearer [token].
However, when reading the JWT docs, I have come across nothing that refers to the correct manner in which to send the refresh token. A brief search returned that it should be sent in the body of a POST request, however, given I am currently sending both tokens in all fetch requests I make, this would not work for GET requests.
Should I be sending both tokens in all requests? If so how should I send the refresh token in a GET request. Given it is stored in the client cookies, I have considered extracting it from there, though I'm curious if there is a better/more generally accepted method.

refresh token local storage after refreshed on server

How do you handle jwt token after it has expired?
I really need to know what is the best thing to handle token in local storage,
On my server, if the token on header is expired, I refresh it, and the token in local storage will not updated after it refresh from server,
I could think each respond after refresh token, I will set the token on each response then set it to local storage, for every request which need the token, but I am sure it is not efficient and too much work, right?
what is the best practice to handle refresh token from server for client-side?
I'm not sure if this helps or not but in many workflows it's the client driving the request. If possible, it may help to simplify the problem:
The client needs a valid token to make a request
If you're able to make this assumption then this can allow you to push the responsibility of token management to the client. Then the server will reject ANY request with an invalid token and return unauthorized to the client. This makes it the clients responsibility to re-auth or refresh by keeping track of token validity.
This separates concerns so that the server doesn't need to have token management and refresh on each request.
I'm basing this on Single Page Application Authentication workflows like described https://auth0.com/docs/architecture-scenarios/spa-api

Two token security: JWT/Oauth2 in regular cookie plus OAuth2 refresh token in HttpOnly cookie?

I'm exploring JWT and OAuth2 for a Javascript Single-Page-App which will make calls to a backend server-side API. I've come up with a security process that involves using two tokens and gives me the advantage of avoiding the need to have an additional server-side session storage:
The first time the client JS app is loaded up, user sends username/password over SSL to OAuth2 server. The server will set a cookie (normal cookie that is readable by client, without any HttpOnly flag set) that contains a JWT with an OAuth2 access token inside it's claims (along with some other non-confidential data in the JWT claims, ie. user's first/last name, country, role/permission). The server will also set a HttpOnly cookie that will contain the OAuth2 refresh token.
The cookies set by the server will be included on every request from the client automatically (always over SSL), so the server will receive the JWT (see step 3) and both confirm the signature and confirm the OAuth2 access token. The server will also confirm the refresh token. Since the server is checking the access token and refresh token against the OAuth2 database on each request, this gives us the ability to revoke access (which we would not be able to do with the JWT signature alone). We can do a "hard" revoke which revokes both access and refresh token. And we can do a "soft" revoke which just revokes the access token (for instances where perhaps some data that we keep in the JWT claim gets updated, ie. user changes their name or country or role). A soft revoke would be invisible to the client end user (it wouldn't disrupt their logged in status).
In step 2 above, the server will actually look for the JWT in a specific header set by the client (instead of the cookie set by the server). For example, the client JS app will read the JWT from the cookie and then set the JWT in another part of the header. By requring the client to explicitly set a header key/value containing the JWT shows that the client was able to read it's own cookie, thus preventing against XSRF (cross-site request forgery).
The HttpOnly cookie that contains the refresh token ensures we are protected against XSS (ie. some malicious javascript that sneaked its way onto our client). If our JWT was stolen, access still wouldn't be granted because the refresh token was not also seen or stolen by the JS.
With this approach we get all these benefits:
We don't need a server-side session storage. Since we are hitting an OAuth2 server then we can simply just include some extra data in the JWT that we return (non-confidential data). We wouldn't need to re-query/refresh the data in the JWT every time, but perhaps only when the OAuth token is revoked (ie. was revoked when some user data was changed that we include in the JWT's). No need to tackle the storage/scaling requirement that comes with using sessions. The client JS app can use this data like any other app would normally use sessions. For instance I can display a user's name on every "page" in the app. We could also just use websockets, but the JWT is a good backup place for adding some data if we need it.
We are protected against XSRF.
We are protected against XSS.
We can revoke access and also log users out (which is not easily possible with JWT alone).
SSL prevents man-in-the-middle attacks.
The JWT adds a little extra security hurdle for attackers to pass versus just a normal JSON object serialized in the cookie. The attacker would need to get the server-side key for signing JWT's (in addition to OAuth access). The JWT is also a standard, so easier for a trusted developer to work with.
The JWT can be easily passed down to other micro-services sitting behind the OAuth layer to use service-to-service. We can pass it around as "session like" data access to all the services on a request. If a service want's to change something in that data, then they can inform OAuth2 server and it will "soft" revoke the user's current JWT (not really much different from the process with a session storage) and provide a new one.
I haven't exactly seen anyone detail a security process like this yet. Many I see seem to only talk about using JWT with an OAuth2 access token inside and don't elaborate much more. So my question is, does this approach indeed provide the benefits I listed above? If not, what am I missing here and what security hole have I not covered for?

Client application and token authentication/validation OAuth

I am trying to implement OAuth with my javascript client application.
I already have the server up and running.
My workflow is as following:
Open app
Check if token is present
Validate the token
If not present or not valid go to oauth server for the token
Get back to app and repeat 2 and 3
I everything is ok show my app
I am not sure how to implement point 2. I understand that I need to make another call to the server for this but where is the validation endpoint?
I only have /authorize, /user and /logout
Also how should the request be formed? Do I attach token as a GET parameter and thats all?
What if somebody intercepts valid the token?
Depends on your application, but since you have a javascript web application, that most probably can't keep it's credentials secret, you'll need to implement the Implicit Grant as stated in the OAuth 2.0 spec. If however your application CAN keep it's credentials secret, you should implement the Client Credentials Grant (server side application) because it's more secure.
I am not sure how to implement point 2
You should store your access token somewhere in your web application, for instance in localStorage.
The first time a user will access your web application, the user will have NO access token and NO session with your authorization server. Your web application could see if you have an access token by doing something like:
if (!localStorage.getItem('accessToken') {
window.location.replace('https://your-authorization-server/authorize?response_type=token&client_id=<CLIENT_ID>&redirect_uri=<CALLBACK_URL>&scope=<SCOPE>');
}
If there's no access token, you'll need to redirect to your authorization server so that the user can log in with the authorization server. After the user has logged in, the authorization server will redirect the user back to your web application (after the user has granted permission to whatever resource your web application likes to access on behalf of said user) with a valid access token. This access token must be exposed as a hash fragment named access_token, i.e:
https://web-app.com#access_token=123456789X
Now your web application can extract the access token and store it somewhere.
I understand that I need to make another call to the server for this
but where is the validation endpoint? I only have /authorize, /user
and /logout
Your authorization server requires a token validation endpoint. This endpoint will be used by your web application to validate said token (the one you stored somewhere, for instance localStorage). When this endpoint is called with an access token and it turns out the token is valid, the user can continue, otherwise the user will be redirected to the authorization server. If the user already has a session with the authorization server, the user will be redirected back immediately with a new access token, otherwise the user needs to authenticate (login) first.
Also how should the request be formed? Do I attach token as a GET
parameter and thats all?
Some send a GET request with the access token as a url query parameter, others send a POST request with the access token as the payload of the request body.
What if somebody intercepts the valid token?
Always use https and your access token should be valid for a limited amount of time.
Something to keep in mind is that because your application can't keep it's credentials secret, you need to Implement the Implicit Grant, this means you immediately receive the access token when the authorization server authorized the web application based on Client Id and domain. As opposed to Client Credentials Grant where you first receive an Authorization Code that needs to be exchanged for an access token. When using Implicit Grant you can NOT use Refresh Tokens. This means the user NEEDS to go through the entire flow with the authorization server to obtain a new access token. But this isn't really a big deal, because the user will already be logged in with the authorization server, resulting in an immediate redirect, so when implemented correctly in the web application, the user won't notice.
This is just covering it in broad strokes, it really helped me (and I advise you) to read the OAuth 2.0 spec. Hope this helps you out a bit, OAuth is a complex subject!

Down-scoping Oauth access-token, possible?

I am developing an open source javascript project. It has client side database, Oauth Connect login and bear-token base access to cross domain resource servers like (GData, Google cloud storage, AWS via proxy). The main focus is on consumer cloud data (you know, developer got free data storage).
The main goal to provide database to the web app without using backend server. It is achieved by keeping Oauth 2 refresh token in the server, providing access token to the web app so that it can populate its client side database, directly from resource servers. Dumb proxy server may be necessary for updating back to the resource server.
Login user may share his data to other login user. Server provides access token as necessary. In that case I wish to down-grade the access token. Generally once a new user start using the app, the server request off-line multiple scopes read-write grant. Currently, I as far I can understand a refresh token can generate access token of exact scopes.
Is that possible to request a down-graded access token from an offline refresh token? Even down grading from read-write to read-only is very useful.

Categories

Resources