Single sign-on flow using JWT for cross domain authentication

67,182

Solution 1

The user should be redirected to the authentication server again and get a new token (JWT), one that is specifically targeted for example2.com. This is how OpenID Connect and any other cross-domain federated SSO protocol works.

Solution 2

Redirecting the user to the central authentication service when the user is not logged in to request credentials and issue a new authentication token is the common scenario in Single Sign On systems using well-known protocols like oauth2 or OpenId Connect

However when this schema is used across domains the main drawback is that the user is going to be redirected and authenticated each time he navigates to other domain due to same-origin policy: the access token can not be shared between domains (example2.com can not access data of example1.com), so the target domain will treat user as unauthenticated, redirecting him to the central SSO service.

To prevent the authentication service from re-requesting credentials, it is common to have a session cookie (not an access token), but there is a tecnique to share data across domains using browser localStorage/cookies and a iframe pointing to an intermediate domain sso.example.com

  1. To authenticate the user in example1.com, redirect him to the authentication server in sso.example.com, issue a JWT after authenticating and store it in the localStorage of this domain. After this, redirect user to the origin domain example1.com

  2. Create an iframe in example2.com pointing to sso.example.com. The iframe in sso.example.com reads the JWT token and sends a message to the parent page

  3. The parent page receives the message and gets the attached token continuing with the SSO flow

There is no problem with same-origin policy because sso.example.com has access to its localStorage and the communication between iframe and the parent page is allowed if origin and target domains recognize each other (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

This method is perfectly compatible with SSO flows. It is just a way to share the authentication token without redirections and avoid unnecessary log-ins when the domains are federated

Solution 3

Not sure if this answers you question, but if your main goal is single sign-on, I think a simple reverse proxy would solve your problem (at least the cross-domain storage one).

So example1.com example2.com

would become something like

example.com/example1

example.com/example2

(And from a user side, this is usually cleaner)

If that is not an option, you might have to set up so that when a user authenticates in 1 domain, it uses AJAX/hidden iframes to create an authentication with the other domains as well (sending a 1 time token via url if you must).

and if THAT'S not an option, you might have to resort to username+pin, as browsers are getting stricter about cross-domain interaction.

Share:
67,182
electrotype
Author by

electrotype

Spincast is an highly flexible and open source Java web framework, based on Guice.

Updated on August 08, 2020

Comments

  • electrotype
    electrotype over 3 years

    There is a lot of information on the web about using JWT (Json Web Token) for authentication. But I still didn't find a clear explanation of what the flow should be when using JWT tokens for a single sign-on solution in a multiple domains environment.

    I work for a company which has a lot of sites on different hosts. Let's use example1.com and example2.com. We need a single sign-on solution, which means if a user authenticates on example1.com, we want him to also be authenticated on example2.com, automatically.

    Using the OpenId Connect flow, I understand that the user who wants to authenticate on example1.com will first be redirected to the authentication server (or OP : "OpenId Provider"). The user authenticates on that server which then redirects him back to the original example1.com site with a signed JWT token. (I understand there is another flow which returns an intermediate token that itself can be exchanged for the real JWT token later on, but I don't think this is required for us)...

    So now the user is back on example1.com and is authenticated! He can make requests, passing the JWT token in a Authentication header and the server is able to verify the signed JWT and therefore is able to identify the user. Nice!

    First question :

    How should the JWT token be stored on the client? There is, again, a lot of information about this, and people seem to agree that using Web Storage is the way to go rather than good old cookies. We want the JWT to be persistent between browser restarts so let's use Local Storage, not Session Storage...

    Now the user can restart his browser and he will still be authenticated on example1.com, as long as the JWT token is not expired!

    Also, if example1.com needs to make an Ajax request to another of our domains, I understand configuring CORS would allow that. But our main use case is not cross-domain requests, it's having a single sign-on solution!

    Therefore, the main question :

    Now, what should the flow be, if the user goes to example2.com and we want him to be authenticated, using the JWT token he already has? Local Storage doesn't seem to allow cross-domain access so at this point the browser can't read the JWT token to make requests to example2.com!

    Should :

    • The user be redirected to the authentication server again? When the user authenticated for example1.com, the authentication server may have set a cookie on the user so this new authentication request for example2.com could use that cookie to see that the user is already authenticated and immediately redirects him back to example2.com with the same JWT token?
    • Or can the browser, on example2.com, access the JWT token without having to go to the authentication server again? I see there are cross-storage solutions, but are those widely used? Are they the suggested solution to a cross domain SSO environment?

    We don't want anything fancy, we would be happy with the mostly used solution!

    • Muhammad Usama Mashkoor
      Muhammad Usama Mashkoor about 3 years
      Did you find any solution for this?
  • electrotype
    electrotype over 8 years
    But without the user having to resend the authentication credentials (username/password for example) since it's SSO, right? So how is it done? Should the authentication server set a standard cookie on the user the first time, so it can automatically authenticate him when this user is back from a new domain?
  • Hans Z.
    Hans Z. almost 8 years
    Apart from this solution not adhering to a standard, usually in cross-domain SSO one crosses administrative boundaries and in that case using the very same JWT for both domains would open the possibility for an application owner in one domain to impersonate the user in the other domain
  • pedrofb
    pedrofb over 7 years
    Thanks @HansZ. We have actually implemented this solution in order to have a single administration of multiple domains with dozens of applications and the same users. The operation is similar to google system (relatively speaking)
  • Christiaan Westerbeek
    Christiaan Westerbeek over 5 years
    But what if the user configured the browser to block all cookies?
  • AnBisw
    AnBisw about 5 years
    I guess a warning should be placed about cookies that "the site may not work properly if your browser blocks cookies"
  • Hans Z.
    Hans Z. almost 4 years
    single-signon does not necessarily imply that the user has an ongoing session tracked by a cookie: its defining characteristic is that one re-uses the same credentials against the same Identity Provider to gain access to different 3rd-party applications i.e. no cookie required, just re-use of the same creds
  • Tomas
    Tomas almost 3 years
    @electrotype yes that's exactly right. Cookies have to be set up and present on auth server and therefore user will be recognized, authenticated, token will be automatically issued and user will be redirected at second domain without any interaction (no need to ask for credentials)
  • Ham
    Ham almost 3 years
    Based on my (very little) frontend knowledge , when it comes to storing the access/refresh tokens in web frontend, if the frontend is SPA, does that mean it is not necessarily store your token to cookie ? (maybe the frontend keeps the token in memory instead ?) if yes then it is also OK even when end-users block cookies
  • daniel sp
    daniel sp over 2 years
    I tried this. The call to sso.example.com returns the cookie, but it is not saved in the browser for the sso.example.com domain. Any idea what could I be missing?