Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support PKCE in OIDC connector #3188

Closed
wants to merge 1 commit into from

Conversation

vixus0
Copy link

@vixus0 vixus0 commented Nov 8, 2023

Overview

This adds a configuration option enablePKCE to the OIDC connector to send code challenge and verifier parameters as required for PKCE.

What this PR does / why we need it

Some OIDC providers require the PKCE flow, so a code challenge must be passed to the authorize endpoint, and a code verifier must be sent on the subsequent authorization token exchange.

Dex currently supports PKCE for downstream clients, but not for upstream OIDC providers.
Dynamic configuration using the OAuth2 discovery metadata isn't possible as the coreos/go-oidc library currently doesn't expose code_challenge_methods_supported in the Provider.

Special notes for your reviewer

Does this PR introduce a user-facing change?

* Adds the OIDC connector configuration option `enablePKCE` to send code
  challenge and verifier parameters to upstream OIDC providers as required for
  PKCE.

Some OIDC providers require the PKCE flow, so a code challenge must be
passed to the authorize endpoint, and a code verifier must be sent on
the subsequent authorization token exchange.

This adds the configuration option `enablePKCE` to the OIDC connector to
enable these PKCE parameters.

Signed-off-by: Anshul Sirur <[email protected]>
@vixus0 vixus0 force-pushed the connector-oidc-pkce branch from ac34641 to 32afd90 Compare November 8, 2023 14:36
@vixus0 vixus0 changed the title Support PKCE in OIDC connector feat: support PKCE in OIDC connector Nov 8, 2023
@vixus0 vixus0 changed the title feat: support PKCE in OIDC connector feat: Support PKCE in OIDC connector Nov 8, 2023
@cameronbrunner
Copy link

I did a similar implementation here: #3195 with the biggest difference being that mine generates a new verifier for each login session. As 'oauth2.GenerateVerifier()' just gets a single random string it is stated that a new one should be done for each authorization: https://cs.opensource.google/go/x/oauth2/+/refs/tags/v0.15.0:pkce.go;l=22
Any thoughts on my PR?

@cameronbrunner
Copy link

Sorry I missed your PR when I did mine... I had been thinking about it prior to your work and missed this one when I started mine.

Copy link
Member

@nabokihms nabokihms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some questions regarding the implementation. The idea lgtm!

@@ -184,6 +187,11 @@ func (c *Config) Open(id string, logger log.Logger) (conn connector.Connector, e
c.PromptType = "consent"
}

pkceVerifier := ""
if c.EnablePKCE {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know if we need an option for this? We can rely on what the provider exposes via the discovery endpoint.

  "code_challenge_methods_supported": [
    "S256",
    "plain"
  ],

If the code_challenge_methods_supported section is present, we can use PKCE.

Copy link
Member

@nabokihms nabokihms Dec 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vixus0 my bad, I overlooked the info from your first post

Dynamic configuration using the OAuth2 discovery metadata isn't possible as the coreos/go-oidc library currently doesn't expose code_challenge_methods_supported in the Provider.

Let's leave a comment in the code about this for other developers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, after checking the docs once again, there is an option to extract the provider's metadata by using https://pkg.go.dev/github.com/coreos/go-oidc/v3/oidc#Provider.Claims


if c.pkceVerifier != "" {
c.pkceVerifier = oauth2.GenerateVerifier()
opts = append(opts, oauth2.S256ChallengeOption(c.pkceVerifier))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S256 can be unsupported by the provider. It is required to either clarify that Dex only supports the S256 challenge or provide support for others.

We can rename the option EnablePKCE to PKCEChallenge instead of the boolean variable and let users specify the type of challenge they want to use.

@@ -265,6 +275,12 @@ func (c *oidcConnector) LoginURL(s connector.Scopes, callbackURL, state string)
if s.OfflineAccess {
opts = append(opts, oauth2.AccessTypeOffline, oauth2.SetAuthURLParam("prompt", c.promptType))
}

if c.pkceVerifier != "" {
c.pkceVerifier = oauth2.GenerateVerifier()
Copy link

@cameronbrunner cameronbrunner Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this setting just one verifier for all clients? It appears that if 2 clients were logging in at the same time the first one's verifier would be overwritten by the seconds preventing use of the proper verifier during token exchange (line 317-320).

@ClaudioNTT
Copy link

Hello everyone, will the merge request be approved? When will it be merged?

@johnvan7
Copy link

johnvan7 commented Sep 16, 2024

Hi, I've tested this feature and it works well!
LGTM !

@ClaudioNTT
Copy link

ClaudioNTT commented Sep 16, 2024

Hi, I've tested this feature and it works well! LGTM !

very good!! same here, I've tested with Ping Federate and it works perfectly @nabokihms
LGTM tooo! 🚀

@nabokihms
Copy link
Member

nabokihms commented Sep 20, 2024

This pr cannot be merged I’m afraid:

  • it has conflicts
  • I’m still waiting for requested fixes

If anybody wants to finish the work, feel free to do this

@vixus0
Copy link
Author

vixus0 commented Oct 22, 2024

Unfortunately I wasn't able to dedicate any more time to these changes, but I'm glad the feature was picked up again!

Closing in favour of #3777.

@vixus0 vixus0 closed this Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants