diff --git a/pkg/services/authn/clients/oauth.go b/pkg/services/authn/clients/oauth.go index c27a63b1d03..e0a4bc676dc 100644 --- a/pkg/services/authn/clients/oauth.go +++ b/pkg/services/authn/clients/oauth.go @@ -112,7 +112,7 @@ func (c *OAuth) Authenticate(ctx context.Context, r *authn.Request) (*authn.Iden if err != nil { return nil, errOAuthMissingPKCE.Errorf("no pkce cookie found: %w", err) } - opts = append(opts, oauth2.SetAuthURLParam(codeVerifierParamName, pkceCookie.Value)) + opts = append(opts, oauth2.VerifierOption(pkceCookie.Value)) } clientCtx := context.WithValue(ctx, oauth2.HTTPClient, c.httpClient) @@ -184,16 +184,13 @@ func (c *OAuth) RedirectURL(ctx context.Context, r *authn.Request) (*authn.Redir var plainPKCE string if c.oauthCfg.UsePKCE { - pkce, hashedPKCE, err := genPKCECode() + verifier, err := genPKCECodeVerifier() if err != nil { return nil, errOAuthGenPKCE.Errorf("failed to generate pkce: %w", err) } - plainPKCE = pkce - opts = append(opts, - oauth2.SetAuthURLParam(codeChallengeParamName, hashedPKCE), - oauth2.SetAuthURLParam(codeChallengeMethodParamName, codeChallengeMethod), - ) + plainPKCE = verifier + opts = append(opts, oauth2.S256ChallengeOption(plainPKCE)) } state, hashedSate, err := genOAuthState(c.cfg.SecretKey, c.oauthCfg.ClientSecret) @@ -233,8 +230,8 @@ func (c *OAuth) Logout(ctx context.Context, user identity.Requester, info *login return &authn.Redirect{URL: redirctURL}, true } -// genPKCECode returns a random URL-friendly string and it's base64 URL encoded SHA256 digest. -func genPKCECode() (string, string, error) { +// genPKCECodeVerifier returns code verifier that 128 characters random URL-friendly string. +func genPKCECodeVerifier() (string, error) { // IETF RFC 7636 specifies that the code verifier should be 43-128 // characters from a set of unreserved URI characters which is // almost the same as the set of characters in base64url. @@ -249,14 +246,12 @@ func genPKCECode() (string, string, error) { raw := make([]byte, 96) _, err := rand.Read(raw) if err != nil { - return "", "", err + return "", err } ascii := make([]byte, 128) base64.RawURLEncoding.Encode(ascii, raw) - shasum := sha256.Sum256(ascii) - pkce := base64.RawURLEncoding.EncodeToString(shasum[:]) - return string(ascii), pkce, nil + return string(ascii), nil } func genOAuthState(secret, seed string) (string, string, error) { diff --git a/pkg/services/authn/clients/oauth_test.go b/pkg/services/authn/clients/oauth_test.go index 893bc6934f9..b9d5cf57e0c 100644 --- a/pkg/services/authn/clients/oauth_test.go +++ b/pkg/services/authn/clients/oauth_test.go @@ -268,7 +268,7 @@ func TestOAuth_RedirectURL(t *testing.T) { { desc: "should generate redirect url with pkce if configured", oauthCfg: &social.OAuthInfo{UsePKCE: true}, - numCallOptions: 2, + numCallOptions: 1, authCodeUrlCalled: true, }, } @@ -404,6 +404,12 @@ func TestOAuth_Logout(t *testing.T) { } } +func TestGenPKCECodeVerifier(t *testing.T) { + verifier, err := genPKCECodeVerifier() + assert.NoError(t, err) + assert.Len(t, verifier, 128) +} + type mockConnector struct { AuthCodeURLFunc func(state string, opts ...oauth2.AuthCodeOption) string social.SocialConnector