Single Sign Out

#1

I am currently implementing SSO on multiple applications using OIDC. I am not sure how to handle single-sign-out in a Single-Page App (SPA) for token-based authentication.

Consider two applications. Application A is a standard Spring MVC application that uses the OAuth2 Authorization Code flow, and application B is a SPA using the implicit flow. Both applications use Okta for SSO, so if a user signs into one application, they have an active Okta session, and if they sign out of the app, the Okta SSO session is terminated.

If a user has signed into Application A, when they navigate to Application B they are automatically signed in via SSO, which is to be expected. However, If the user logs out of Application A and then navigates to application B, currently app B still loads and allows access to apis because it has a valid OAuth2 access token stored in browser local storage. I would like application B to require the user to re-authenticate before making any other requests.

What is the recommended approach for doing single sign out in a SPA, since there is no way to have the identity provider send a ‘signout’ request to a server endpoint?

A couple of possible solutions I have thought of are:

  • Create one-time-use access tokens that must be re-generated with every request.
  • Check for an active IDP session any time Application B wants to make a request to our apis.

I am hesitant to use either of those two solutions because they require an additional request to the IDP any time the user interacts with the app. Are the any other strategies to solve this problem?

As an additional note, I am familiar with this OIDC draft spec (http://openid.net/specs/openid-connect-session-1_0.html#RPLogout) which brings up the notion of front-channel logout. I would love to be able to do something like this using the okta logout_redirect_uri value in an application’s profile. Has anyone had success implementing this?

#2

I don’t know if it’ll help, but I wrote about how to do front-channel logout with Spring Boot and Angular a few weeks ago. https://developer.okta.com/blog/2018/06/18/spring-boot-angular-auth-code-flow#logout-with-okta

#3

Hi @dhouston,

Okta currently doesn’t support the Single Sign Out scenario, where all tokens (access, ID, and/or refresh) will be revoked when a user’s session has ended. That being said, Okta does support Token Revocation and RP-Initiated Logout, where the SSO session can be terminated by passing the idToken to the end_session_endpoint, and follow-up calls can be made to revoke an accessToken and/or refreshToken.

One thing to note, it is common for applications to map a user’s session lifetime to the token lifetime. Essentially, the IDP’s session operates independently to your application; however it can be utilized for silently refreshing tokens (SPA flow). There doesn’t necessarily need to be parity between the IDP session and your application’s session times.

As an alternative, you could shorten the token expiry time to 5 or 10 min, which reduces a user’s authorized time after the SSO session ends. This might be the best option for you, as your application will most likely check for an active SSO session once the token expires.

Hope this helps a bit! Please let me know if anything seems unclear.

#4

Hi @jmelberg,

I am having a similar issue implementing single logout, and wanted to add to the conversation here.

Regarding use of the OIDC revoke endpoint, the docs state that a client may only revoke its own tokens.

Regarding shortening the token expiry time, an application with a valid refresh token would still able to obtain new access tokens unless the refresh token is revoked. However, revoking another application’s refresh tokens does not seem possible using the OIDC endpoints.

Is there any other way? Is there anything on the roadmap for better support of Single Logout scenario, e.g. to support back-channel logout or logout callbacks?

So far, the only thing I see available that can logout the user’s SSO session and revoke all tokens is the Clear User Sessions endpoint; however, giving an application access to this would also allow access to other user management endpoints and this would not be desirable.

#5

Identity Server 4 supports single sign-out. For each app you configure a link to sign out. IDS stores sign out links for all apps in a hidden iframe, and when you sign out from one app or IDS those links are used behind the scenes to sign out from app apps. Is it possible to implement something like this in Okta ?