OpenId Connect renew access_token in SPA
Asked Answered
P

3

6

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.
Pegeen answered 29/5, 2018 at 9:57 Comment(1)
Is there any reason which cause you to avoid Implicit flow ?Propagate
P
2

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.

Propagate answered 30/5, 2018 at 8:34 Comment(4)
Thanks. You suggestion looks good. I wonder if it's possible/secure to embed IdP login page into Client page via iframe?Pegeen
@Pegeen I would say to avoid that and utilise the browser and redirect to complete the flow. Some indeity providers may avoid loading there login page in an iframe (by setting relevant headers)Propagate
External IdP usually doesn't want his site to be loaded in an untrusted environment. But in my case, IdP, RP, and RS are mine. What you think ?Pegeen
@Pegeen You may go ahead with such an approach. But in future, you may want to support other identity providers. So be mindful about such needs tooPropagate
T
2

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.

Tenpins answered 30/5, 2018 at 10:1 Comment(0)
T
1

Further to previous answers, the latest OAuth working group guidance for SPAs no longer recommends use of the implicit flow.

If you have simple, shared domain app (IdP, RS and client on a single domain) then you should consider not using OAuth at all. From the doc:

OAuth and OpenID Connect provide very little benefit in this deployment scenario, so it is recommended to reconsider whether you need OAuth or OpenID Connect at all in this case. Session authentication has the benefit of having fewer moving parts and fewer attack vectors. OAuth and OpenID Connect were created primarily for third-party or federated access to APIs, so may not be the best solution in a same-domain scenario.

If you are using OIDC/OAuth in a SPA, they recommend the auth code flow with PKCE.

Tercel answered 24/9, 2019 at 0:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.