10
votes

I'm trying to understand how to implement the logout feature in a Single Sign On architecture using Json Web Tokens.

Let's say we have :

  • example1.com
  • example2.com
  • authserver.com

When the user has to authenticate on example1.com, he is redirected to authserver.com which validates the user credentials, creates a signed JWT token and redirects the user back to example1.com with this token. example1.com will then set a cookie (or a LocalStorage key) and the user will be authenticated on example1.com, for as long as the token is not expired. No more call to authserver.com is required to identify the user.

The user then goes to example2.com, which participates in the SSO architecture. The user needs to be authenticated there too, so example2.com also redirects the user to authserver.com which recognizes the user (using a cookie it has set the first time), creates a new JWT token and automatically redirects the user back to example2.com. example2.com will then set a cookie (or a LocalStorage key) and the user will be authenticated on example2.com, for as long as the token is not expired. No more call to authserver.com is required to identify the user.

Now, how can a "logout" feature be implemented?

If the user logs out on example1.com, the JWT token on example1.com is deleted and the user shouldn't be authenticated there anymore. But as soon as he tried to reach a protected area, example1.com will redirect him to authserver.com, the user will be recognized and automatically logged in again... Even if he just logged out!

Quetion 1) So I guess that when the user logs out on example1.com, a call to authserver.com must be done to remove the cookie set by authserver.com so the user won't be logged in automatically anymore?

Quetion 2) If so, what about example2.com? Should the user still be authenticated there? If not, what is the suggested flow so example2.com knows that the JWT token it has for the user isn't valid anymore?

2

2 Answers

5
votes

1) https://openid.net/specs/openid-connect-session-1_0.html#RPLogout is one spec (there are other specs for different strategies) to sign out of the authserver as well. It defines an end_session_endpoint that your example1.com would redirect to; note that the authserver signs the user out and can redirect back to the RP's post_logout_redirect_uri.

2) I think that depends on what you want it to do. You may not want to kill the example2.com session, in which case example2.com would carry on. The JWT for example2.com is still valid. If you want to logout of all your clients, it's a bit more complicated but possible. In my project, logging out of the one client and the authserver was what we wanted.

8
votes

Alternatively you could also implement a cross domain SSO without openid, only using JWT on client side, like google web apps.

The advantage is that you do not need to redirect the user to the server to know if the user is logged in. Logout and JWT changes could be automatically synchronized between tabs.

After Authserver.com returns the JWT to example1, store it in localStorage, but use an intermediate domain sso.example.com through an iframe. Include this iframe in example1 and example2 (pointing to sso.example.com). The iframe will read JWT and send a message to the page containing the token.

When the user logs out or change the active user, the iframe also could send a message to parent, so you can sync all your sites (if you want)

No problem with CORS because sso.example.com have access to its localStorage. And communication between iframes is allowed if origin and destination are recognized (see http://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage)

To simplify development, we have released recently a cross domain SSO with JWT at https://github.com/Aralink/ssojwt

Summarizing your questions as this architecture 1) Clean the JWT in localStorage and send a javascript event 2) Listen the event and decides what to do