Add a SSO flow to Laravel Passport

Viewed 607

We are trying to implement a SSO solution using Laravel Passport. There is already a question about this topic but I think this one is more about the nitty-gritty.

Our requirements are:

  • A Laravel Passport service running on passport.com
  • Some first-party sites on various domains: foo.com, bar.com
  • Users can log in to foo.com and bar.com by typing their access details directly (Password Grant)
  • If a user logs in to foo.com and then they visit bar.com they should be automatically logged in

Based on my understanding of Oauth2, the system should work like the following:

Initial login flow:

  1. The user types in their details on foo.com
  2. foo.com makes a request to passport.com/oauth/token using a Password Grant and retrives an Access Token and a Refresh Token. Additionally, a SSO Token is generated and returned.
  3. foo.com redirects the user to passport.com/sso/passthrough , passing the SSO Token and a return URL as query parameters.
  4. passport.com saves the token as a cookie and then redirects to the return URL.
  5. The user returns on foo.com and they can use the site

Note that the redirect to passport.com MUST take place, as otherwise browsers like Safari and Chrome in incognito will consider passport.com to be a third-party domain and the cookie will be blocked.

SSO flow:

  1. The user visits bar.com
  2. bar.com makes an AJAX request to passport.com/oauth/authorize using a SSO Grant and the redirect URI bar.com/sso/return
  3. On passport.com, the SSO Grant looks for the SSO Token in the cookies and if the token is found, an authorization code is produced and sent bar.com/sso/return as a redirect. Because AJAX requests don't handle redirects, control passes directly to bar.com.
  4. bar.com exchanges the authorization code for an access token and returns a successful AJAX response
  5. bar.com receives the AJAX response and triggers a page refresh since the user is now logged in

For clarity, the SSO Token, SSO Grant, passport.com/sso/passthrough and bar.com/sso/return routes are not part of Laravel Passport; they are new concepts that we are implementing here.

The questions here are:

  1. This flow looks to me like it should work. Am I missing anything?
  2. Does this introduce any vulnerability into the Oauth2 flow? The Access Token and Refresh Token are never displayed to the client, but the SSO Token is. If an attacker steals it, I'm guessing they could potentially impersonate the user.
  3. The Oauth2 protocol and Laravel Passport are stateless. By adding a cookie we are adding state. Is this a necessary evil or can it be done in a different way?
  4. Should the SSO Token be saved to the cookie directly or should there be a different kind of token or authorization code there?
  5. Any tips for implementing the SSO Grant and SSO Token?
0 Answers
Related