Fix integration tests to work with the username and sub claims

Signed-off-by: Margo Crawford <margaretc@vmware.com>
This commit is contained in:
Ryan Richard 2020-12-15 17:16:08 -08:00 committed by Margo Crawford
parent a10d219049
commit 91af51d38e
3 changed files with 18 additions and 12 deletions

View File

@ -62,18 +62,19 @@ func TestSuccessfulCredentialRequest(t *testing.T) {
{ {
name: "jwt authenticator", name: "jwt authenticator",
authenticator: func(t *testing.T) corev1.TypedLocalObjectReference { authenticator: func(t *testing.T) corev1.TypedLocalObjectReference {
return library.CreateTestJWTAuthenticator(ctx, t) return library.CreateTestJWTAuthenticator(ctx, t, "email")
}, },
token: func(t *testing.T) (string, string, []string) { token: func(t *testing.T) (string, string, []string) {
pinnipedExe := buildPinnipedCLI(t) pinnipedExe := buildPinnipedCLI(t)
credOutput, _ := runPinniedLoginOIDC(ctx, t, pinnipedExe) credOutput, _ := runPinniedLoginOIDC(ctx, t, pinnipedExe)
token := credOutput.Status.Token token := credOutput.Status.Token
// By default, the JWTAuthenticator expects the username to be in the "sub" claim and the // By default, the JWTAuthenticator expects the username to be in the "username" claim and the
// groups to be in the "groups" claim. // groups to be in the "groups" claim.
username, groups := getJWTSubAndGroupsClaims(t, token) // We are configuring pinniped to set the username to be the "email" claim from the token.
username, groups := getJWTEmailAndGroupsClaims(t, token)
return credOutput.Status.Token, username, groups return token, username, groups
}, },
}, },
} }
@ -233,18 +234,18 @@ func safeDerefStringPtr(s *string) string {
return *s return *s
} }
func getJWTSubAndGroupsClaims(t *testing.T, jwt string) (string, []string) { func getJWTEmailAndGroupsClaims(t *testing.T, jwt string) (string, []string) {
t.Helper() t.Helper()
token, err := jwtpkg.ParseSigned(jwt) token, err := jwtpkg.ParseSigned(jwt)
require.NoError(t, err) require.NoError(t, err)
var claims struct { var claims struct {
Sub string `json:"sub"` Email string `json:"email"`
Groups []string `json:"groups"` Groups []string `json:"groups"`
} }
err = token.UnsafeClaimsWithoutVerification(&claims) err = token.UnsafeClaimsWithoutVerification(&claims)
require.NoError(t, err) require.NoError(t, err)
return claims.Sub, claims.Groups return claims.Email, claims.Groups
} }

View File

@ -169,7 +169,7 @@ func TestSupervisorLogin(t *testing.T) {
tokenResponse, err := downstreamOAuth2Config.Exchange(oidcHTTPClientContext, authcode, pkceParam.Verifier()) tokenResponse, err := downstreamOAuth2Config.Exchange(oidcHTTPClientContext, authcode, pkceParam.Verifier())
require.NoError(t, err) require.NoError(t, err)
expectedIDTokenClaims := []string{"iss", "exp", "sub", "aud", "auth_time", "iat", "jti", "nonce", "rat"} expectedIDTokenClaims := []string{"iss", "exp", "sub", "aud", "auth_time", "iat", "jti", "nonce", "rat", "username"}
verifyTokenResponse(t, tokenResponse, discovery, downstreamOAuth2Config, env.SupervisorTestUpstream.Issuer, nonceParam, expectedIDTokenClaims) verifyTokenResponse(t, tokenResponse, discovery, downstreamOAuth2Config, env.SupervisorTestUpstream.Issuer, nonceParam, expectedIDTokenClaims)
// token exchange on the original token // token exchange on the original token
@ -226,6 +226,10 @@ func verifyTokenResponse(
idTokenClaimNames = append(idTokenClaimNames, k) idTokenClaimNames = append(idTokenClaimNames, k)
} }
require.ElementsMatch(t, expectedIDTokenClaims, idTokenClaimNames) require.ElementsMatch(t, expectedIDTokenClaims, idTokenClaimNames)
expectedUsernamePrefix := upstreamIssuerName + "?sub="
require.True(t, strings.HasPrefix(idTokenClaims["username"].(string), expectedUsernamePrefix))
require.Greater(t, len(idTokenClaims["username"].(string)), len(expectedUsernamePrefix),
"the ID token Username should include the upstream user ID after the upstream issuer name")
// Some light verification of the other tokens that were returned. // Some light verification of the other tokens that were returned.
require.NotEmpty(t, tokenResponse.AccessToken) require.NotEmpty(t, tokenResponse.AccessToken)

View File

@ -170,7 +170,7 @@ func CreateTestWebhookAuthenticator(ctx context.Context, t *testing.T) corev1.Ty
// authenticator within the test namespace. // authenticator within the test namespace.
// //
// CreateTestJWTAuthenticator gets the OIDC issuer info from IntegrationEnv().CLITestUpstream. // CreateTestJWTAuthenticator gets the OIDC issuer info from IntegrationEnv().CLITestUpstream.
func CreateTestJWTAuthenticator(ctx context.Context, t *testing.T) corev1.TypedLocalObjectReference { func CreateTestJWTAuthenticator(ctx context.Context, t *testing.T, usernameClaim string) corev1.TypedLocalObjectReference {
t.Helper() t.Helper()
testEnv := IntegrationEnv(t) testEnv := IntegrationEnv(t)
@ -193,9 +193,10 @@ func CreateTestJWTAuthenticator(ctx context.Context, t *testing.T) corev1.TypedL
jwtAuthenticator, err := jwtAuthenticators.Create(createContext, &auth1alpha1.JWTAuthenticator{ jwtAuthenticator, err := jwtAuthenticators.Create(createContext, &auth1alpha1.JWTAuthenticator{
ObjectMeta: testObjectMeta(t, "jwt-authenticator"), ObjectMeta: testObjectMeta(t, "jwt-authenticator"),
Spec: auth1alpha1.JWTAuthenticatorSpec{ Spec: auth1alpha1.JWTAuthenticatorSpec{
Issuer: testEnv.CLITestUpstream.Issuer, Issuer: testEnv.CLITestUpstream.Issuer,
Audience: testEnv.CLITestUpstream.ClientID, Audience: testEnv.CLITestUpstream.ClientID,
TLS: tlsSpec, TLS: tlsSpec,
UsernameClaim: usernameClaim,
}, },
}, metav1.CreateOptions{}) }, metav1.CreateOptions{})
require.NoError(t, err, "could not create test JWTAuthenticator") require.NoError(t, err, "could not create test JWTAuthenticator")