From 1f25319077f9b371440a66eebbd3d1e0edcbfda9 Mon Sep 17 00:00:00 2001 From: rithu john Date: Wed, 21 Mar 2018 16:15:17 -0700 Subject: [PATCH] oidc authentication: email_verified claim is not required for JWT validation --- .../pkg/authenticator/token/oidc/oidc.go | 25 +++++++++++++----- .../pkg/authenticator/token/oidc/oidc_test.go | 26 ++++++++++++++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go index c33c540c00..8a1030fd5e 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc.go @@ -284,14 +284,18 @@ func (a *Authenticator) AuthenticateToken(token string) (user.Info, bool, error) } if a.usernameClaim == "email" { - // Check the email_verified claim to ensure the email is valid. + // If the email_verified claim is present, ensure the email is valid. // https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims - var emailVerified bool - if err := c.unmarshalClaim("email_verified", &emailVerified); err != nil { - return nil, false, fmt.Errorf("oidc: parse 'email_verified' claim: %v", err) - } - if !emailVerified { - return nil, false, fmt.Errorf("oidc: email not verified") + if hasEmailVerified := c.hasClaim("email_verified"); hasEmailVerified { + var emailVerified bool + if err := c.unmarshalClaim("email_verified", &emailVerified); err != nil { + return nil, false, fmt.Errorf("oidc: parse 'email_verified' claim: %v", err) + } + + // If the email_verified claim is present we have to verify it is set to `true`. + if !emailVerified { + return nil, false, fmt.Errorf("oidc: email not verified") + } } } @@ -347,3 +351,10 @@ func (c claims) unmarshalClaim(name string, v interface{}) error { } return json.Unmarshal([]byte(val), v) } + +func (c claims) hasClaim(name string) bool { + if _, ok := c[name]; !ok { + return false + } + return true +} diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go index 412c32a6fe..1e1248a674 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc/oidc_test.go @@ -287,7 +287,7 @@ func TestToken(t *testing.T) { wantErr: true, }, { - // If "email_verified" isn't present, assume false + // If "email_verified" isn't present, assume true name: "no-email-verified-claim", options: Options{ IssuerURL: "https://auth.example.com", @@ -305,6 +305,30 @@ func TestToken(t *testing.T) { "email": "jane@example.com", "exp": %d }`, valid.Unix()), + want: &user.DefaultInfo{ + Name: "jane@example.com", + }, + }, + { + name: "invalid-email-verified-claim", + options: Options{ + IssuerURL: "https://auth.example.com", + ClientID: "my-client", + UsernameClaim: "email", + now: func() time.Time { return now }, + }, + signingKey: loadRSAPrivKey(t, "testdata/rsa_1.pem", jose.RS256), + pubKeys: []*jose.JSONWebKey{ + loadRSAKey(t, "testdata/rsa_1.pem", jose.RS256), + }, + // string value for "email_verified" + claims: fmt.Sprintf(`{ + "iss": "https://auth.example.com", + "aud": "my-client", + "email": "jane@example.com", + "email_verified": "false", + "exp": %d + }`, valid.Unix()), wantErr: true, }, {