feat: Send PKCE (S256) in OpenID Connect SSO login #125
Merged
Robert Navarro opened 1 week ago

I'm running OneDev 16.8.6 with Kanidm as the OpenID Connect provider. Kanidm enforces PKCE on OAuth2 clients by default, and OneDev's OpenID connector sends no code_challenge, so I turned PKCE off for the OneDev client before the first login. I didn't try an unpatched login with PKCE enforced; Kanidm's code rejects an authorization request without code_challenge in that mode. I searched the tracker and found no existing issue or PR for PKCE.

This adds PKCE with the S256 method to OpenIdConnector. buildAuthUrl creates a code verifier for each login and keeps it in the session next to the state, and the authorization request carries the matching code_challenge. handleAuthResponse takes the verifier out of the session and sends it as code_verifier on the token request. A response without a stored verifier is rejected with the existing "Unsolicited OIDC authentication response" message.

The GitHub, Entra ID and Twitch connectors extend OpenIdConnector, so they pick this up too. Discord extends SsoConnector directly and is unchanged.

PKCE is always on. RFC 7636 asks clients to send it to every server, and RFC 6749 requires servers to ignore parameters they don't recognize, so a provider without PKCE support sees a normal code flow. GitHub and Entra ID document S256 support. Twitch doesn't mention PKCE and I couldn't test it. If you'd prefer a per-provider setting to turn it off, I can add one.

I applied the patch to my 16.8.6 server and turned PKCE enforcement back on for the Kanidm client. The SSO login works, and the authorization request carries code_challenge_method=S256. The module has no test sources, so I didn't add a unit test.

I used an AI coding assistant to help write this change, and I reviewed and tested it myself.

Commits were merged into target branch
  • feat: Send PKCE (S256) in OpenID Connect SSO login
    Generate a code verifier for each login attempt and keep it in the session next to the state. The authorization request carries the S256 code challenge, and the token request carries the verifier, which is removed from the session once read.
    
    This lets OneDev log in through providers that enforce PKCE, such as Kanidm. Providers that do not implement PKCE ignore the extra parameters (RFC 6749 sections 3.1 and 3.2, RFC 7636 section 5).
    1 week ago
  • Work Horse commented 1 week ago

    Reviewed commit baa51a05. No actionable correctness or security issues found in the patch. Checked verifier randomness, S256 challenge generation, state validation before verifier consumption, token-request serialization, and inherited connector behavior against Nimbus 11.28 sources and RFC 7636.

    Validation: mvn -U -pl server-plugin/server-plugin-sso-openid -am -DskipTests compile passed, including reactor dependencies. Live provider logins were not exercised. No code changes.

  • Work Horse approved 1 week ago
  • Robin Shen changed merge strategy 1 week ago
    Previous Value Current Value
    CREATE_MERGE_COMMIT
    SQUASH_SOURCE_BRANCH_COMMITS
  • Robin Shen changed merge strategy 1 week ago
    Previous Value Current Value
    SQUASH_SOURCE_BRANCH_COMMITS
    CREATE_MERGE_COMMIT
  • Robin Shen merged 1 week ago (merge commit: d792a0e3 )
1/1
Submitter Robert Navarro
Target main
Source forks/rnavarro/server:feat/oidc-pkce
Reviewers
Merge Strategy
Create Merge Commit
Watchers (3)
Reference
PR OD-125
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover