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.