Add integration test for multiple audience in structured authn
Signed-off-by: Anish Ramasekar <anish.ramasekar@gmail.com> Kubernetes-commit: 0feb1d5173c94e28da79963fb296296b005dd6a1
This commit is contained in:
parent
8242123b04
commit
1bc99127a6
|
@ -242,7 +242,7 @@ type Issuer struct {
|
|||
AudienceMatchPolicy AudienceMatchPolicyType `json:"audienceMatchPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// AudienceMatchPolicyType is a set of valid values for Issuer.AudienceMatchPolicy
|
||||
// AudienceMatchPolicyType is a set of valid values for issuer.audienceMatchPolicy
|
||||
type AudienceMatchPolicyType string
|
||||
|
||||
// Valid types for AudienceMatchPolicyType
|
||||
|
|
|
@ -219,6 +219,7 @@ func validateClaimValidationRules(compiler authenticationcel.Compiler, celMapper
|
|||
|
||||
compilationResult, err := compileClaimsCELExpression(compiler, &authenticationcel.ClaimValidationCondition{
|
||||
Expression: rule.Expression,
|
||||
Message: rule.Message,
|
||||
}, fldPath.Child("expression"))
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -578,10 +578,8 @@ func (v *idTokenVerifier) verifyAudience(t *oidc.IDToken) error {
|
|||
if v.audiences.Len() == 0 {
|
||||
return fmt.Errorf("oidc: invalid configuration, audiences cannot be empty")
|
||||
}
|
||||
for _, aud := range t.Audience {
|
||||
if v.audiences.Has(aud) {
|
||||
return nil
|
||||
}
|
||||
if v.audiences.HasAny(t.Audience...) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("oidc: expected audience in %q got %q", sets.List(v.audiences), t.Audience)
|
||||
|
|
|
@ -1554,6 +1554,39 @@ func TestToken(t *testing.T) {
|
|||
Name: "jane",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple-audiences in authentication config, multiple matches",
|
||||
options: Options{
|
||||
JWTAuthenticator: apiserver.JWTAuthenticator{
|
||||
Issuer: apiserver.Issuer{
|
||||
URL: "https://auth.example.com",
|
||||
Audiences: []string{"random-client", "my-client", "other-client"},
|
||||
AudienceMatchPolicy: "MatchAny",
|
||||
},
|
||||
ClaimMappings: apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: "username",
|
||||
Prefix: pointer.String(""),
|
||||
},
|
||||
},
|
||||
},
|
||||
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),
|
||||
},
|
||||
claims: fmt.Sprintf(`{
|
||||
"iss": "https://auth.example.com",
|
||||
"aud": ["not-my-client", "my-client", "other-client"],
|
||||
"azp": "not-my-client",
|
||||
"username": "jane",
|
||||
"exp": %d
|
||||
}`, valid.Unix()),
|
||||
want: &user.DefaultInfo{
|
||||
Name: "jane",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple-audiences in authentication config, no match",
|
||||
options: Options{
|
||||
|
@ -1585,6 +1618,82 @@ func TestToken(t *testing.T) {
|
|||
}`, valid.Unix()),
|
||||
wantErr: `oidc: verify token: oidc: expected audience in ["my-client" "random-client"] got ["not-my-client"]`,
|
||||
},
|
||||
{
|
||||
name: "nuanced audience validation using claim validation rules",
|
||||
options: Options{
|
||||
JWTAuthenticator: apiserver.JWTAuthenticator{
|
||||
Issuer: apiserver.Issuer{
|
||||
URL: "https://auth.example.com",
|
||||
Audiences: []string{"bar", "foo", "baz"},
|
||||
AudienceMatchPolicy: "MatchAny",
|
||||
},
|
||||
ClaimMappings: apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: "username",
|
||||
Prefix: pointer.String(""),
|
||||
},
|
||||
},
|
||||
ClaimValidationRules: []apiserver.ClaimValidationRule{
|
||||
{
|
||||
Expression: `sets.equivalent(claims.aud, ["bar", "foo", "baz"])`,
|
||||
Message: "audience must exactly contain [bar, foo, baz]",
|
||||
},
|
||||
},
|
||||
},
|
||||
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),
|
||||
},
|
||||
claims: fmt.Sprintf(`{
|
||||
"iss": "https://auth.example.com",
|
||||
"aud": ["foo", "bar", "baz"],
|
||||
"azp": "not-my-client",
|
||||
"username": "jane",
|
||||
"exp": %d
|
||||
}`, valid.Unix()),
|
||||
want: &user.DefaultInfo{
|
||||
Name: "jane",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "audience validation using claim validation rules fails",
|
||||
options: Options{
|
||||
JWTAuthenticator: apiserver.JWTAuthenticator{
|
||||
Issuer: apiserver.Issuer{
|
||||
URL: "https://auth.example.com",
|
||||
Audiences: []string{"bar", "foo", "baz"},
|
||||
AudienceMatchPolicy: "MatchAny",
|
||||
},
|
||||
ClaimMappings: apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: "username",
|
||||
Prefix: pointer.String(""),
|
||||
},
|
||||
},
|
||||
ClaimValidationRules: []apiserver.ClaimValidationRule{
|
||||
{
|
||||
Expression: `sets.equivalent(claims.aud, ["bar", "foo", "baz"])`,
|
||||
Message: "audience must exactly contain [bar, foo, baz]",
|
||||
},
|
||||
},
|
||||
},
|
||||
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),
|
||||
},
|
||||
claims: fmt.Sprintf(`{
|
||||
"iss": "https://auth.example.com",
|
||||
"aud": ["foo", "baz"],
|
||||
"azp": "not-my-client",
|
||||
"username": "jane",
|
||||
"exp": %d
|
||||
}`, valid.Unix()),
|
||||
wantErr: `oidc: error evaluating claim validation expression: validation expression 'sets.equivalent(claims.aud, ["bar", "foo", "baz"])' failed: audience must exactly contain [bar, foo, baz]`,
|
||||
},
|
||||
{
|
||||
name: "invalid-issuer",
|
||||
options: Options{
|
||||
|
|
Loading…
Reference in New Issue