fix(sso): support skipping the OIDC UserInfo endpoint at registration#5386
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryHigh Risk Overview The in-app register route now always sets OIDC discovery is refactored into Reviewed by Cursor Bugbot for commit 45b6d31. Configure here. |
Greptile SummaryFixes Azure AD/Entra ID OIDC login failures on better-auth 1.6.x by giving operators a way to skip the UserInfo endpoint and force the ID-token/JWKS claims path. It also stops better-auth from silently re-populating
Confidence Score: 5/5Safe to merge; all three previously-identified correctness issues have been addressed in this commit and the new tests provide good coverage of the edge cases. The changes are surgical and well-tested: No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[POST /api/auth/sso/register] --> B{providerType === 'oidc'?}
B -- No --> C[Build SAML config]
B -- Yes --> D[SSRF-validate explicit endpoints\nexclude userInfoEndpoint if skipUserInfoEndpoint]
D --> E[fetchOIDCDiscoveryDocument\nalways called]
E --> F{needsDiscovery?\nany of auth/token/jwks missing}
F -- Yes --> G{discoveryResult.ok?}
G -- No --> H[400: surfaced discovery error]
G -- Yes --> I[Merge missing endpoints from discovery\nSSRF-validate discovered endpoints\nselect tokenEndpointAuthentication]
F -- No --> J[selectTokenEndpointAuthentication\nfrom discovery or fallback to client_secret_post]
I --> K{skipUserInfoEndpoint?}
J --> K
K -- Yes --> L[oidcConfig.userInfoEndpoint = undefined]
K -- No --> M[keep userInfoEndpoint]
L --> N[Validate required endpoints present]
M --> N
N --> O[oidcConfig.skipDiscovery = true]
O --> P[auth.api.registerSSOProvider]
C --> P
P --> Q[200 success]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[POST /api/auth/sso/register] --> B{providerType === 'oidc'?}
B -- No --> C[Build SAML config]
B -- Yes --> D[SSRF-validate explicit endpoints\nexclude userInfoEndpoint if skipUserInfoEndpoint]
D --> E[fetchOIDCDiscoveryDocument\nalways called]
E --> F{needsDiscovery?\nany of auth/token/jwks missing}
F -- Yes --> G{discoveryResult.ok?}
G -- No --> H[400: surfaced discovery error]
G -- Yes --> I[Merge missing endpoints from discovery\nSSRF-validate discovered endpoints\nselect tokenEndpointAuthentication]
F -- No --> J[selectTokenEndpointAuthentication\nfrom discovery or fallback to client_secret_post]
I --> K{skipUserInfoEndpoint?}
J --> K
K -- Yes --> L[oidcConfig.userInfoEndpoint = undefined]
K -- No --> M[keep userInfoEndpoint]
L --> N[Validate required endpoints present]
M --> N
N --> O[oidcConfig.skipDiscovery = true]
O --> P[auth.api.registerSSOProvider]
C --> P
P --> Q[200 success]
Reviews (3): Last reviewed commit: "fix(sso): always resolve token auth meth..." | Re-trigger Greptile |
|
Re: |
|
Re: |
|
@cursor review |
…iscarded userInfoEndpoint
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 45b6d31. Configure here.
Summary
userInfoEndpointfrom OIDC discovery on every registration. Azure's Graph UserInfo endpoint doesn't reliably returnemailfor all tenants, so login fails withmissing_user_info.SSO_OIDC_SKIP_USERINFO_ENDPOINTtoregister-sso-provider.tsand a matchingskipUserInfoEndpointfield on the in-app SSO registration API/contract, so operators can force the plugin onto the ID-token/JWKS verification path instead.skipDiscovery: trueinto better-auth's ownregisterSSOProvider(since Sim already resolves/validates endpoints itself) instead of relying on better-auth's redundant internal discovery call, which was silently re-populatinguserInfoEndpointeven when we tried to omit it.tokenEndpointAuthenticationauto-detection from the issuer's discovery document (mirrors better-auth's ownselectTokenEndpointAuthMethod) in both the discovery and all-endpoints-explicit paths, with a non-fatal fallback when discovery is unreachable — avoids silently defaulting toclient_secret_basic, which has a documentedinvalid_clientfailure mode with secrets containing+.Type of Change
Testing
route.test.tscoveringskipDiscovery,skipUserInfoEndpointon/off, discovery-driventokenEndpointAuthenticationselection, and the non-fatal fallback when discovery is unreachable. All 16 tests pass.tsc --noEmitclean onapps/simandpackages/db.bun run check:api-validationpasses.@better-auth/sso@1.6.11source on GitHub (not just our localdistbundle) to confirm the callback claim-precedence logic,overrideUserInfosemantics, andskipDiscovery/discovery-hydration behavior this fix relies on.Checklist