[PR #7800] fix(sso): preserve OAuth provider state through SSO authentication flows #15808

Open
opened 2026-04-13 10:14:09 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7800
Author: @rbayliss
Created: 2/4/2026
Status: 🔄 Open

Base: mainHead: fix/oauth-resume-after-sso


📝 Commits (5)

  • e721c29 Allow SSO plugins to resume OAuth provider flow
  • 03afccd Merge branch 'canary' into fix/oauth-resume-after-sso
  • 1c83d2c Also update OAuth provider client
  • a973f38 Add tests for additionalData in SSO flow
  • 7fb2233 Apply suggestion from @Copilot

📊 Changes

6 files changed (+71 additions, -6 deletions)

View changed files

📝 packages/better-auth/src/api/index.ts (+1 -1)
📝 packages/oauth-provider/src/client.ts (+2 -1)
📝 packages/oauth-provider/src/oauth.ts (+3 -2)
📝 packages/sso/src/oidc.test.ts (+20 -0)
📝 packages/sso/src/routes/sso.ts (+26 -2)
📝 packages/sso/src/saml.test.ts (+19 -0)

📄 Description

When using the SSO plugin (SAML in my case) with the OAuth provider plugin, the OAuth authorization flow would break after SSO authentication. Users would authenticate successfully via SAML or OIDC, but instead of being directed to the consent screen or registration flow, they would be redirected to the callback URL without completing the OAuth flow.

The root cause is that OAuth authorization parameters (client_id, redirect_uri, scope, etc.) were not preserved through the SSO authentication round-trip. The SSO sign-in endpoint was explicitly passing false for additionalData when generating state, and there was no mechanism to restore OAuth state after the IdP callback.

Note: This PR builds on work in https://github.com/better-auth/better-auth/pull/7781

This PR makes the following changes:

  1. OAuth provider "before" hook: Extended to inject oauth_query into additionalData for /sign-in/sso (in addition to existing /sign-in/social and /sign-in/oauth2)
  2. SSO sign-in endpoint: Now accepts additionalData in the request body and passes it through to generateState() (OIDC) and generateRelayState() (SAML)
  3. SSO callback endpoints: After parsing state/RelayState, if OAuth query params are present, calls setOAuthState() to make them available to the OAuth provider's "after" hook
  4. Export setOAuthState: Exposed from better-auth/api to enable cross-plugin OAuth state management

Summary by cubic

Preserves OAuth provider state across SSO (SAML/OIDC) so the OAuth flow resumes after IdP login. Users now reach consent/registration instead of being redirected to the callback early.

  • Bug Fixes
    • Added query to additionalData for /sign-in/sso in the OAuth provider "before" hook.
    • SSO sign-in now accepts additionalData and forwards it to generateState (OIDC) and generateRelayState (SAML).
    • SSO callbacks restore OAuth context by calling setOAuthState when OAuth params are present.
    • Exported setOAuthState from better-auth/api for cross-plugin state handoff.

Written for commit 7fb22332b5. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7800 **Author:** [@rbayliss](https://github.com/rbayliss) **Created:** 2/4/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/oauth-resume-after-sso` --- ### 📝 Commits (5) - [`e721c29`](https://github.com/better-auth/better-auth/commit/e721c290858a915c7fdc0514dbe6380c32d482d0) Allow SSO plugins to resume OAuth provider flow - [`03afccd`](https://github.com/better-auth/better-auth/commit/03afccd8bcf6579a81148e6138662aaa6599c465) Merge branch 'canary' into fix/oauth-resume-after-sso - [`1c83d2c`](https://github.com/better-auth/better-auth/commit/1c83d2cdf35abe253f15531cdeb3c3f824603593) Also update OAuth provider client - [`a973f38`](https://github.com/better-auth/better-auth/commit/a973f38194f70ee909357086adf5e0e299d0a06d) Add tests for additionalData in SSO flow - [`7fb2233`](https://github.com/better-auth/better-auth/commit/7fb22332b5a33323ec41714272ff05a41e64c6d2) Apply suggestion from @Copilot ### 📊 Changes **6 files changed** (+71 additions, -6 deletions) <details> <summary>View changed files</summary> 📝 `packages/better-auth/src/api/index.ts` (+1 -1) 📝 `packages/oauth-provider/src/client.ts` (+2 -1) 📝 `packages/oauth-provider/src/oauth.ts` (+3 -2) 📝 `packages/sso/src/oidc.test.ts` (+20 -0) 📝 `packages/sso/src/routes/sso.ts` (+26 -2) 📝 `packages/sso/src/saml.test.ts` (+19 -0) </details> ### 📄 Description When using the SSO plugin (SAML in my case) with the OAuth provider plugin, the OAuth authorization flow would break after SSO authentication. Users would authenticate successfully via SAML or OIDC, but instead of being directed to the consent screen or registration flow, they would be redirected to the callback URL without completing the OAuth flow. The root cause is that OAuth authorization parameters (client_id, redirect_uri, scope, etc.) were not preserved through the SSO authentication round-trip. The SSO sign-in endpoint was explicitly passing false for additionalData when generating state, and there was no mechanism to restore OAuth state after the IdP callback. Note: This PR builds on work in https://github.com/better-auth/better-auth/pull/7781 This PR makes the following changes: 1. OAuth provider "before" hook: Extended to inject oauth_query into additionalData for /sign-in/sso (in addition to existing /sign-in/social and /sign-in/oauth2) 2. SSO sign-in endpoint: Now accepts additionalData in the request body and passes it through to generateState() (OIDC) and generateRelayState() (SAML) 3. SSO callback endpoints: After parsing state/RelayState, if OAuth query params are present, calls setOAuthState() to make them available to the OAuth provider's "after" hook 4. Export setOAuthState: Exposed from better-auth/api to enable cross-plugin OAuth state management <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Preserves OAuth provider state across SSO (SAML/OIDC) so the OAuth flow resumes after IdP login. Users now reach consent/registration instead of being redirected to the callback early. - **Bug Fixes** - Added query to additionalData for /sign-in/sso in the OAuth provider "before" hook. - SSO sign-in now accepts additionalData and forwards it to generateState (OIDC) and generateRelayState (SAML). - SSO callbacks restore OAuth context by calling setOAuthState when OAuth params are present. - Exported setOAuthState from better-auth/api for cross-plugin state handoff. <sup>Written for commit 7fb22332b5a33323ec41714272ff05a41e64c6d2. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-13 10:14:09 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#15808