Skip to content

Fix MCP OAuth login with OIDC SSO#30449

Open
Vishnuujain wants to merge 5 commits into
mainfrom
fix-mcp-oauth-issuer
Open

Fix MCP OAuth login with OIDC SSO#30449
Vishnuujain wants to merge 5 commits into
mainfrom
fix-mcp-oauth-issuer

Conversation

@Vishnuujain

@Vishnuujain Vishnuujain commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #30445

Problem

ChatGPT (or other MCP tool) login break for companies using SSO login (OIDC). Server check id from wrong source expect Google, get company's own login server. Login fail, 500 error.

Fix

  • MCP login flow now always fetch identity fresh from company's own SSO server, not reuse old web session shortcut.
  • Track login state (state/nonce/PKCE) properly through round trip so callback can match.

Web login path is untouched (guarded behind !isMcpFlow).

Greptile Summary

This PR completes the MCP OIDC authorization-code round trip before redirecting to the external provider.

  • Skips the active-session JWT shortcut for MCP login requests.
  • Persists OIDC state, nonce, and PKCE verifier against the pending MCP authorization request before redirect.
  • Restores provider credentials for the MCP callback while leaving normal web login behavior unchanged.
  • Centralizes MCP session attribute names and adds focused authentication-flow tests.

Confidence Score: 5/5

The PR appears safe to merge with no blocking failures remaining.

No blocking failure remains.

Important Files Changed

Filename Overview
openmetadata-mcp/src/main/java/org/openmetadata/mcp/McpServer.java Registers the pre-redirect hook that links generated OIDC state to the pending MCP authorization request.
openmetadata-mcp/src/main/java/org/openmetadata/mcp/server/auth/provider/UserSSOOAuthProvider.java Places the pending request identifier in the session before initiating OIDC login and verifies that state linking occurred.
openmetadata-mcp/src/main/java/org/openmetadata/mcp/server/auth/handlers/McpCallbackServlet.java Reuses the centralized MCP authorization-request session key during direct token callback handling.
openmetadata-service/src/main/java/org/openmetadata/service/security/AuthenticationCodeFlowHandler.java Forces MCP requests through the complete external OIDC flow and hands validated provider credentials to the MCP callback.
openmetadata-service/src/test/java/org/openmetadata/service/security/AuthenticationCodeFlowHandlerTest.java Covers MCP shortcut suppression, pre-redirect state persistence, callback recognition, and web-login isolation.

Sequence Diagram

sequenceDiagram
  participant Client as MCP Client
  participant MCP as MCP OAuth Provider
  participant Login as OIDC Login Handler
  participant Store as Pending Auth Store
  participant IdP as External IdP
  participant Callback as MCP Callback
  Client->>MCP: Authorization request
  MCP->>Store: Create pending request
  MCP->>Login: Start MCP login
  Login->>Store: Persist state, nonce, and PKCE verifier
  Login->>IdP: Redirect to authorization endpoint
  IdP->>Login: Return authorization code and state
  Login->>IdP: Exchange code for provider tokens
  Login->>Callback: Forward validated OIDC credentials
  Callback->>Store: Resolve pending request
  Callback-->>Client: Return MCP authorization result
Loading

Reviews (5): Last reviewed commit: "fix(mcp): hand provider OIDC credentials..." | Re-trigger Greptile

Context used:

@github-actions github-actions Bot added the safe to test Add this label to run secure Github workflows on PRs label Jul 24, 2026
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

🔴 Playwright Results — workflow failed

Validated commit ff8775ba285999302b6da14b734515585cc3e191 in Playwright run 30094665316, attempt 1.

✅ 0 passed · ❌ 0 failed · 🟡 0 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky

Pipeline and setup failures (5)

  • Duration-aware shard planning finished with status failure.
  • Fixture cache restoration finished with status skipped.
  • Seeded fixture preparation finished with status skipped.
  • The Playwright shard matrix was unexpectedly skipped.
  • No expected Playwright shards were declared.

Performance

⚪ Performance metrics unavailable; see the CI and reporting failures above.

Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

Comment thread openmetadata-mcp/src/main/java/org/openmetadata/mcp/McpServer.java
@gitar-bot

This comment was marked as outdated.

@Vishnuujain
Vishnuujain requested a review from a team as a code owner July 24, 2026 12:52
@gitar-bot

gitar-bot Bot commented Jul 24, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Refactors MCP OAuth to use the full OIDC round-trip and bypass the internal active-session shortcut, resolving the ID token issuer mismatch. Clean implementation with robust test coverage and no open findings.

✅ 2 resolved
Quality: Misleading log/dead path after removing early return in MCP flow

📄 openmetadata-mcp/src/main/java/org/openmetadata/mcp/server/auth/provider/UserSSOOAuthProvider.java:359-373
This commit moved the pending-request linking into handleLogin() via the persister and removed the early return that previously followed it. Control now falls through to the pac4j session-attribute scan (lines 359-431). Since AuthenticationCodeFlowHandler stores state via sessionService.createPendingSession (DB), not the HttpSession, pac4jState is always null for the MCP round-trip, so the code lands in the else branch and logs the 'active-session shortcut detected ... id_token in URL fragment' message — which is now factually wrong because MCP explicitly bypasses the active-session shortcut (AuthenticationCodeFlowHandler.java:387). This will mislead operators debugging MCP OAuth. Consider re-adding an early return for the MCP flow after handleLogin(), or removing/adjusting this now-dead pac4j-extraction block and its log message.

Edge Case: Persister silently no-ops if session/auth-request id missing

📄 openmetadata-mcp/src/main/java/org/openmetadata/mcp/McpServer.java:194-207 📄 openmetadata-service/src/main/java/org/openmetadata/service/security/AuthenticationCodeFlowHandler.java:439-444
The registered persister only calls updatePac4jSession when request.getSession(false) is non-null and MCP_AUTH_REQUEST_ID is a String; otherwise it silently does nothing, and persistMcpPendingState also swallows a null persister. If linking fails, handleSSOAuthorization still returns 'SSO_REDIRECT_INITIATED' (the pac4j-extraction else-branch logs success on a committed response), so the returning /callback?state= will later fail with 'state not found or expired' with no earlier signal. Given setAttribute runs just before handleLogin the happy path is fine, but consider logging a warning when the persister cannot resolve the auth-request id so this failure mode is diagnosable.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@Vishnuujain Vishnuujain changed the title fix(mcp): use full OIDC round-trip for MCP OAuth to avoid id_token issuer mismatch Fix MCP OAuth login with OIDC SSO Jul 24, 2026
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

✅ PR checks passed

The linked issue has a description and all required Shipping project fields set. Thanks!

@Vishnuujain Vishnuujain added To release Will cherry-pick this PR into the release branch and removed To release Will cherry-pick this PR into the release branch labels Jul 24, 2026
@Vishnuujain
Vishnuujain enabled auto-merge (squash) July 24, 2026 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP OAuth fails with id_token issuer mismatch when OIDC SSO is configured

2 participants