Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenId Connect renew access_token in SPA

Trying to implement OpenId Connect in Web Application consisting of following components

  • Identity Provider
  • Resource server
  • Single Page Application acting as Client.

Identity Provider and Resource Server are the same application.

SPA use Password Flow to get access_token and stores into the cookie. Storing access_token into cookie has it's security threads, but's it's a different story.

Problem

access_token issued by IdP is expired after 30 min and SPA needs to renew token without asking users for credentials again.

Solution

IdP returns refresh_token along with access_token. Whenever SPA gets 401 from Resource Server, it sends refresh_token to IdP and get's new access_token back.

Problem

Sending refresh_token to SPA is bad practice.

A Single Page Application (normally implementing Implicit Grant) should not under any circumstances get a Refresh Token. The reason for that is the sensitivity of this piece of information. You can think of it as user credentials since a Refresh Token allows a user to remain authenticated essentially forever. Therefore you cannot have this information in a browser, it must be stored securely.

Suggested solution

When the Access Token has expired, silent authentication can be used to retrieve a new one without user interaction, assuming the user's SSO session has not expired.

I think Silent Authentication is not applicable to Password Flow when IdP and Resource Server is same application. access_token issued by IdP is only piece of information which can be used to authorize against Resource Server/IdP after its expiration, how a client can convince IdP to issue new access_token? (without sending refresh_token)

Found angular-oauth2-oidc library which uses refresh_token to renew access_token.

What is best practice/solution in this case to renew access_token?

technical details

  • Identity Provider - ASP.NET Core + Openiddict library.
  • SPA - AngularJs application.
like image 588
tchelidze Avatar asked May 29 '18 09:05

tchelidze


People also ask

How do I refresh OIDC token?

To refresh your access token as well as an ID token, you send a token request with a grant_type of refresh_token . Be sure to include the openid scope when you want to refresh the ID token. If the refresh token is valid, then you get back a new access and the refresh token.

Where is refresh token Spa stored?

You Can Store Refresh Token In Local Storage Storing tokens in browser local storage provides persistence across page refreshes and browser tabs; however, if malicious users managed to run JavaScript in the SPA using a cross-site scripting (XSS) attack, they could retrieve the tokens stored in local storage.

How do I renew my JWT token?

Web applications To refresh the token, your API needs a new endpoint that receives a valid, not expired JWT and returns the same signed JWT with the new expiration field. Then the web application will store the token somewhere.

What happens when refresh token expires?

When an access token expires, a refresh token is used to get a new access token and it also returns a new refresh token. Now if this new access token expires & a new/updated refresh token is used to get the next access token, it will also receive a newer refresh token.


2 Answers

Single page applications must not receive refresh tokens. That has been established rules in OAuth 2.0 and OpenID Connect.

One good option I see here is to use Implicit Flow. This will establish a front channel session from your browser to Identity Provider. With password grant type you do a back-channel call (POST), so you don't get such session.

Usually this is a cookie which points to information about previous logged in status (these are identity provider specifics). With completion of the flow, SPA will receive the access token. As you figured out, it will expire. But once that happens, SPA can trigger another implicit flow, but this time with prompt query parameter.

prompt

Space delimited, case sensitive list of ASCII string values that specifies whether the Authorization Server prompts the End-User for reauthentication and consent. The defined values are: none , login, consent and select_account

If you identity provider maintain a long lived session (ex:- few hours or days) or if it maintain a remember me cookie, SPA could use prompt=none making it to skip login step from identity provider. Basically, you are getting browser based SSO behaviour with this.

like image 133
Kavindu Dodanduwa Avatar answered Oct 13 '22 20:10

Kavindu Dodanduwa


Using the Resource Owner Password Credentials flow defeats the refresh token storage argument: instead of not being able to store the refresh token in a secure place, the SPA would now have to store the Resource Owner credentials in a secure place (assuming you want to avoid requesting username/password from the user frequently). The Implicit grant was designed for usage with an SPA, so it is better to stick with that.

like image 2
Hans Z. Avatar answered Oct 13 '22 22:10

Hans Z.