Legacy SSO solution like Drupal's own Bakery Single Sign-On System is based on HTTP cookies. It works by storing user information (username, roles, etc) generated by a centralized authorization server (auth server) in the cookies, then by leveraging the feasibility of sharing cookies cross multiple subdomains, transferring the user state to other websites. The biggest drawback of this approach is it only works for websites/browsers, where HTTP cookies are used.

With API-First direction and micro-services architecture, there is a need to support SSO for API Services as well as Websites. During the research, @bojanz 's Using OpenID Connect for Single Sign-On with Drupal comes up, which uses OAuth 2.0 + OpenID Connect to achieve SSO. This issue is to offer an alternative to use OAuth 2.0 + JWT (Token format standard) alone to achieve SSO. For more information about Stateless SSO with OAuth2 and JWT, please see:

The reasons to provide an alternative approach is below:

  1. Although JWT is another technology, it is only a format, therefore one less technology to use comparing to OpenID Connect
  2. Stateless SSO has better performance for resources servers
  3. simple_oauth has more maintenance support than oauth2_server
  4. simple_oauth has already uses JWT

The main purpose of this issue is to figure out how to organize the code for simple_oauth based SSO solution:

  1. Make the existing simple_oauth JWT compliance: #2900182: Add standard JWT claims to generated token
  2. Write a module to let site builder to configure private claims in JWT, shall we call this module simple_oauth_sso
  3. Implement JWT (register claims + private claims) validation part for resources server built on Drupal, shall we create a module based on social_auth? or start from scratch and put the code in the simple_oauth_sso?
  4. Link/redirect user profile on resources servers (Drupal) to auth server
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

skyredwang created an issue. See original summary.

e0ipso’s picture

This sounds like an ambitious plan, I like it!!

I'm not sure it's relevant, but if you want to have a decentralized SSO architecture you should probably look into the JWT module. That module is recommended whenever you want to generate the JWTs outside of Drupal and then use them to authorize Drupal requests.


That being said,

Write a module to let site builder to configure private claims in JWT

I think this is low priority. We have the tools to create private claims via normalizers, this should be a nice to have. Someone setting this up will require a strong tech background, and they'll know how to override a normalizer. We probably should focus efforts on the rest first.

Implement JWT (register claims + private claims) validation part for resources server built on Drupal, shall we create a module based on social_auth?

I lean towards social_auth. But I may be biased. If we go this way this would be the big bulk of this effort.

Something very important that we are missing is documentation. Every setup will have different requirements, so we need people to be able to know how to implement those.

skyredwang’s picture

I think this is low priority. We have the tools to create private claims via normalizers, this should be a nice to have.

What if we just normalize the entire $user entity (with proper permission)? Not sure if there is a limit on JWT payload. Then, in the future, we can come back to offer configurations.

e0ipso’s picture

What if we just normalize the entire $user entity (with proper permission)?

I think that out-of-the-box, this module should only provide the required claims and the optional ones that are in the user entity without any other custom fields. Any reason to have everything exposed in the JWT? Would that reason be applicable to everyone using the JWT?

skyredwang’s picture

Would that reason be applicable to everyone using the JWT?

Yes. "Everyone" here means every resource server would use JWT for SSO.

e0ipso’s picture

What I meant is, we're going to increase the token size significantly if we add all the properties of the user object. Will every site using these JWT benefit from the increased size? I think the answer is no, but I'm interested to learn what's your motivation to add all the user properties in here by default. The alternative is that each site implements the normalizer to add any additional properties they may need.

skyredwang’s picture

we're going to increase the token size significantly if we add all the properties of the user object.

Yes.

The alternative is that each site implements the normalizer to add any additional properties they may need.

Yes.

The reason to include a default (maybe bloated) all-fields-user info in the token in the potential simple_auth_sso module is that people don't need to implement their own normalizer, and SSO would work out of box for people who don't know Drupal too well.

But, I don't have a strong preference. As you said, people who need to configure SSO are probably with strong tech background, therefore, they can write down a simple normalizer.

alan_blake’s picture

Add private claims to the jwt token by creating hook alters.

e0ipso’s picture

Priority: Normal » Major
Status: Active » Needs work

@alan_blake this looks great!

Just a couple of details.

  1. Can we use a normalizer instead of a hook alter?
  2. Can we add a test for this?

This is the current priority at the moment.

skyredwang’s picture

Added #2932519: Make the user authorization step optional as a sub-task for improving UX when OAuth2 auth code grant is used for SSO.

alan_blake’s picture

This patch add access token self as parameter.

@e0ipso #91&2. I have no idea. The patch only effects on output JWT token and there is no change to access token entity.

e0ipso’s picture

+++ b/src/Entities/AccessTokenEntity.php
@@ -11,4 +15,30 @@ class AccessTokenEntity implements AccessTokenEntityInterface {
+    \Drupal::moduleHandler()->invokeAll('private_claim', [&$private_claim, $this]);

Change the hook name to simple_oauth_private_claims.


Why do we need to pass $this?

e0ipso’s picture

@alan_blake I think that a hook will do for now.

Could you copy and paste an example of the hook implementation for SSO? That will help someone to implement the necessary tests. Also, we will need hook documentation in simple_oauth.api.php.

bojanz’s picture

Just for future reference:

Although JWT is another technology, it is only a format, therefore one less technology to use comparing to OpenID Connect

OpenID Connect is a UserInfo endpoint (with a standardized list of claims) and a JWT id_token. You're not avoiding OpenID Connect, just reimplementing it in a slightly different way.

alan_blake’s picture

FileSize
2.54 KB
1.87 KB

This patch change hook name, change it to hook alter, and add hook documentation.

@e0ipso #12 Add `$this` access token entity for reference if someone need the current user information or any useful data.

alan_blake’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 15: 2926720-15.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

skyredwang’s picture

Status: Needs work » Needs review

Change the status to "Needs review", since the testbot failed randomly.

e0ipso’s picture

Status: Needs review » Reviewed & tested by the community
FileSize
1.58 KB
3.04 KB

I made some very minor changes to the patch in #15. Sorry for the delay on this.

  • e0ipso committed 15be6e6 on 8.x-3.x authored by alan_blake
    Issue #2926720 by alan_blake, skyredwang, e0ipso: Stateless SSO based on...
e0ipso’s picture

Status: Reviewed & tested by the community » Fixed

Fixed!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.