Single sign off using OAuth 2

James picture James · Nov 3, 2014 · Viewed 10.1k times · Source

We just have been discussing the login and logout behaviour when using OAuth 2. Let's say we have two webapps A and B using one OAuth provider O (built using the spring-security-oauth2 stack).

When you want to login to A you get redirected to O, enter your credentials, get a session there on O, redirected back to A with an access token and a session is created on A as well.

Now when you want to login to B you get redirected to O, get directly sent back with a token to B because you still have a valid sesison on O and a session is created on B as well (without having to enter your credentials again).

This solves our single sign on problem.

A requirement now is, that when logging out from A or B you are logged out always from both/all apps (single sign off).

Our idea is:

  • Enhance the access token with the current session id
  • If apps A or B want to logout a user, they redirect him to the logout page of O
  • If the user gets logged out from O, all access tokens belonging to the current session on O are removed and the user gets redirected back to A or B
  • The session on A or B gets destroyed
  • A and B check for the validity of their OAuth access token on each request and destroy their session if the token is not valid any more

Do you think this is a valid use case for OAuth 2? How you would you implement single sign off differently?

Answer

Dave Syer picture Dave Syer · Nov 3, 2014

The reason there is no categorical answer to this question is that it all depends on your preference for the user experience, and on the extent to which you trust and/or have control of the apps and servers.

I think there are several ways you might do it and your proposal is definitely workable. I would criticise it only because a) you are using an OAuth token as a session token, and they aren't really the same thing, and b) the "check for the validity of their OAuth access token on each request" part is a bit vague, and I suspect the UX might suffer.

In general it is not always desirable to have single sign-off from a system of OAuth2 client apps - the users might believe that they are logged into separate systems, which happen to authenticate conveniently for them, and not actually want a single sign off experience (e.g. if I log out of one facebook user-provided app, I don't expect to be logged out of my timeline).

If you do need a single sign off and all your apps are in the same domain you can have them share a session cookie scoped to the domain they share. This is dangerous if other apps share the same domain and might not want to participate in the single-sign-on/off behaviour, or if you might not trust them to keep the cookies secret.

With Spring Session you can be more sophisticated and share a session token only among apps that you trust (since you provide only them with access to the session store). That would probably be quite efficient, and I might do it that way in your position, if I had control of all the moving pieces.

It might help to look at the OpenID Connect Session Management Spec to see if there are any ideas there. There is definitely the concept of an identity token (distinct from the access token). I think they suggest doing the validation checks in the browser with scripts in an iframe, which seems awfully ugly, but maybe there really isn't a better way. If you like that idea then you could maybe do the same thing with normal session cookies (no need for the full blown OIDC probably).