4

Given the scenario where a user has logged into my application using the implicit client flow for OpenID Connect where the OP is PingFederate, how can I determine if the user is still logged in if they have closed the application and come back to it within a valid time period?

Kyle Hayes
  • 5,225
  • 8
  • 38
  • 53
  • Maybe I'm not understanding your question. If you got to the point of where the application now has an "ID Token", that's the key. For as long as the token is valid (check expiry time)... But maybe I'm missing something. – Andrew K. May 14 '15 at 12:00
  • I should have mentioned that the application is a browser JavaScript app and at the moment we are not maintaining any session information. When the user closes the application and re-opens, we will not have those keys around. Is it safe to store the ID token in localStorage? – Kyle Hayes May 14 '15 at 17:45
  • 1
    Based on OWASP's security cheatsheet... I'd say no... https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#Local_Storage – Andrew K. May 14 '15 at 19:44
  • Having said that, why would a user that closes a website after completing authN expect the AuthN to still be valid after that closure? [shrug] – Andrew K. May 14 '15 at 19:48
  • 1
    Fair enough, perhaps they just refresh the page for whatever the reason, they are now logged out. Even so, with SSO incorporated into web apps these days, users are expecting and requesting to stay signed into apps for a reasonable period of time. – Kyle Hayes May 15 '15 at 23:04

1 Answers1

5

Resurrecting an old question since OpenID Connect is still widely used. To check if a user is authenticated--either from a previous session with your app, or from a session with another federated application--supply prompt=none in the authentication request. Per the spec, the documentation on prompt=none states:

The Authorization Server MUST NOT display any authentication or consent user interface pages. An error is returned if an End-User is not already authenticated or the Client does not have pre-configured consent for the requested Claims or does not fulfill other conditions for processing the request. The error code will typically be login_required, interaction_required, or another code defined in Section 3.1.2.6. This can be used as a method to check for existing authentication and/or consent.

"Silent Authentication" uses this prompt=none parameter inside an iFrame. Auth0 has some discussion on it, here. In a nutshell, the authentication request is made in an invisible iFrame so that the user agent's main frame is not redirected. Depending on your identity provider (IdP), this may or may not be a valid option. For security reasons, authorization endpoints often deny requests made in frames using the X-Frame-Options: DENY header. Cookie origin policies on the IdP may also prevent silent authentication. That said, the same can be accomplished with e.g. a popup or a full User Agent redirect on initial load of the SPA.

It's worth pointing out that the Implicit Flow has been deprecated for a long time due to a wide range of security issues, many of which do not have sufficient mitigation strategies. The OAuth 2.0 for Browser-Based Apps describes current best practices. Nowadays the Code Flow with PKCE can be used, but it still has a number of security issues that cannot be sufficiently mitigated (again described in the best practices doc).

Code Flow with a back-end session server in an edge device (a server between your SPA and API server) is the best bet security wise. This approach keeps tokens out of the User Agent altogether, helping to mitigate token leaks through XSS attacks, and if done correctly, CSRF attacks become impotent. Pertaining to the question, a long-lived refresh token can be stored in the session server, and can be used to persist authentication across page refreshes or closing the browser. Here is a write-up on this approach.

Addressing one of the comments above: "Why would a user that closes a website after completing authN expect the AuthN to still be valid after that closure?" Because it's better user experience, and expected user experience nowadays. Think about Google, Atlassian, or even this very site (StackOverflow): A user logs in once and pretty much never has to log in again, provided that user interacts with the site frequently and doesn't raise any security red-flags.

Addressing another comment: "If you got to the point of where the application now has an 'ID Token', that's the key. For as long as the token is valid (check expiry time)." Both ID Tokens and Access Tokens should expire quickly, while Refresh Tokens should be long-lived. This way, if the IdP revokes access for a user, the revocation will quickly propagate to all Client applications.

Community
  • 1
  • 1
benbotto
  • 2,291
  • 1
  • 20
  • 32