mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-07 14:05:50 +00:00
add usernameExpression and groupsExpression to JWTAuthenticator CRD
This commit is contained in:
@@ -15,45 +15,65 @@ import (
|
||||
// but is otherwise a straight conversion. The Pinniped type includes TLS configuration which does not need
|
||||
// to be converted because that is applied elsewhere.
|
||||
func convertJWTAuthenticatorSpecType(spec *authenticationv1alpha1.JWTAuthenticatorSpec) apiserver.JWTAuthenticator {
|
||||
usernameClaim := spec.Claims.Username
|
||||
if usernameClaim == "" {
|
||||
usernameClaim = defaultUsernameClaim
|
||||
}
|
||||
|
||||
groupsClaim := spec.Claims.Groups
|
||||
if groupsClaim == "" {
|
||||
groupsClaim = defaultGroupsClaim
|
||||
return apiserver.JWTAuthenticator{
|
||||
Issuer: convertIssuerType(spec),
|
||||
ClaimMappings: convertClaimMappingsType(spec.Claims),
|
||||
ClaimValidationRules: convertClaimValidationRulesType(spec.ClaimValidationRules),
|
||||
UserValidationRules: convertUserValidationRulesType(spec.UserValidationRules),
|
||||
}
|
||||
}
|
||||
|
||||
func convertIssuerType(spec *authenticationv1alpha1.JWTAuthenticatorSpec) apiserver.Issuer {
|
||||
var aud []string
|
||||
if len(spec.Audience) > 0 {
|
||||
aud = []string{spec.Audience}
|
||||
}
|
||||
|
||||
jwtAuthenticator := apiserver.JWTAuthenticator{
|
||||
Issuer: apiserver.Issuer{
|
||||
URL: spec.Issuer,
|
||||
Audiences: aud,
|
||||
},
|
||||
ClaimMappings: apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: usernameClaim,
|
||||
Prefix: ptr.To(""),
|
||||
},
|
||||
Groups: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: groupsClaim,
|
||||
Prefix: ptr.To(""),
|
||||
},
|
||||
Extra: convertExtraType(spec.Claims.Extra),
|
||||
},
|
||||
ClaimValidationRules: convertClaimValidationRulesType(spec.ClaimValidationRules),
|
||||
UserValidationRules: convertUserValidationRules(spec.UserValidationRules),
|
||||
return apiserver.Issuer{
|
||||
URL: spec.Issuer,
|
||||
Audiences: aud,
|
||||
}
|
||||
|
||||
return jwtAuthenticator
|
||||
}
|
||||
|
||||
func convertUserValidationRules(rules []authenticationv1alpha1.UserValidationRule) []apiserver.UserValidationRule {
|
||||
func convertClaimMappingsType(claims authenticationv1alpha1.JWTTokenClaims) apiserver.ClaimMappings {
|
||||
usernameClaim := claims.Username
|
||||
if usernameClaim == "" && claims.UsernameExpression == "" {
|
||||
usernameClaim = defaultUsernameClaim
|
||||
}
|
||||
|
||||
var usernamePrefix *string
|
||||
if usernameClaim != "" {
|
||||
// Must be set only when username claim name is set.
|
||||
usernamePrefix = ptr.To("")
|
||||
}
|
||||
|
||||
groupsClaim := claims.Groups
|
||||
if groupsClaim == "" && claims.GroupsExpression == "" {
|
||||
groupsClaim = defaultGroupsClaim
|
||||
}
|
||||
|
||||
var groupsPrefix *string
|
||||
if groupsClaim != "" {
|
||||
// Must be set only when groups claim name is set.
|
||||
groupsPrefix = ptr.To("")
|
||||
}
|
||||
|
||||
return apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: usernameClaim,
|
||||
Prefix: usernamePrefix,
|
||||
Expression: claims.UsernameExpression,
|
||||
},
|
||||
Groups: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: groupsClaim,
|
||||
Prefix: groupsPrefix,
|
||||
Expression: claims.GroupsExpression,
|
||||
},
|
||||
Extra: convertExtraType(claims.Extra),
|
||||
}
|
||||
}
|
||||
|
||||
func convertUserValidationRulesType(rules []authenticationv1alpha1.UserValidationRule) []apiserver.UserValidationRule {
|
||||
if len(rules) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func Test_convertJWTAuthenticatorSpecType(t *testing.T) {
|
||||
want apiserver.JWTAuthenticator
|
||||
}{
|
||||
{
|
||||
name: "defaults the username and groups claims",
|
||||
name: "defaults the username and groups claims when the usernameExpression and groupExpression are not set",
|
||||
spec: &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: "https://example.com",
|
||||
},
|
||||
@@ -41,6 +41,33 @@ func Test_convertJWTAuthenticatorSpecType(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "does not default the username and groups claims an prefixes when the usernameExpression and groupExpression are set",
|
||||
spec: &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: "https://example.com",
|
||||
Claims: authenticationv1alpha1.JWTTokenClaims{
|
||||
UsernameExpression: `"foo"`,
|
||||
GroupsExpression: `["foo"]`,
|
||||
},
|
||||
},
|
||||
want: apiserver.JWTAuthenticator{
|
||||
Issuer: apiserver.Issuer{
|
||||
URL: "https://example.com",
|
||||
},
|
||||
ClaimMappings: apiserver.ClaimMappings{
|
||||
Username: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: "",
|
||||
Prefix: nil,
|
||||
Expression: `"foo"`,
|
||||
},
|
||||
Groups: apiserver.PrefixedClaimOrExpression{
|
||||
Claim: "",
|
||||
Prefix: nil,
|
||||
Expression: `["foo"]`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "converts every field except for TLS",
|
||||
spec: &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
|
||||
@@ -360,13 +360,13 @@ func TestController(t *testing.T) {
|
||||
Groups: customGroupsClaim,
|
||||
},
|
||||
}
|
||||
someJWTAuthenticatorSpecWithEveryOptionalValue := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
someJWTAuthenticatorSpecWithManyOptionalValues := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer,
|
||||
Audience: goodAudience,
|
||||
TLS: goodOIDCIssuerServerTLSSpec,
|
||||
Claims: authenticationv1alpha1.JWTTokenClaims{
|
||||
Username: "my-custom-username-claim",
|
||||
Groups: customGroupsClaim,
|
||||
Username: "my-custom-username-claim", // note: can't specify this and usernameExpression at the same time
|
||||
Groups: customGroupsClaim, // note: can't specify this and groupsExpression at the same time
|
||||
Extra: []authenticationv1alpha1.ExtraMapping{
|
||||
{
|
||||
Key: "example.com/key-name", // must be a domain and path
|
||||
@@ -387,6 +387,15 @@ func TestController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
someJWTAuthenticatorSpecWithUsernameAndGroupExpressions := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer,
|
||||
Audience: goodAudience,
|
||||
TLS: goodOIDCIssuerServerTLSSpec,
|
||||
Claims: authenticationv1alpha1.JWTTokenClaims{
|
||||
UsernameExpression: "claims.otherUsernameClaim",
|
||||
GroupsExpression: "has(claims.otherGroupsClaim) ? claims.otherGroupsClaim : []", // handles the case where the claim does not exist in the JWT
|
||||
},
|
||||
}
|
||||
invalidClaimsExtraJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer,
|
||||
Audience: goodAudience,
|
||||
@@ -420,6 +429,17 @@ func TestController(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
invalidClaimsMutualExclusiveRulesBothSetJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer,
|
||||
Audience: goodAudience,
|
||||
TLS: goodOIDCIssuerServerTLSSpec,
|
||||
Claims: authenticationv1alpha1.JWTTokenClaims{
|
||||
Username: "user",
|
||||
UsernameExpression: `"user"`,
|
||||
Groups: "groups",
|
||||
GroupsExpression: `["group1"]`,
|
||||
},
|
||||
}
|
||||
invalidClaimsExtraContainsEqualSignJWTAuthenticatorSpec := &authenticationv1alpha1.JWTAuthenticatorSpec{
|
||||
Issuer: goodIssuer,
|
||||
Audience: goodAudience,
|
||||
@@ -1193,13 +1213,13 @@ func TestController(t *testing.T) {
|
||||
wantNamesOfJWTAuthenticatorsInCache: []string{"test-name"},
|
||||
},
|
||||
{
|
||||
name: "Sync: JWTAuthenticator with every optional value: loop will complete successfully and update status conditions",
|
||||
name: "Sync: JWTAuthenticator with many optional values: loop will complete successfully and update status conditions",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *someJWTAuthenticatorSpecWithEveryOptionalValue,
|
||||
Spec: *someJWTAuthenticatorSpecWithManyOptionalValues,
|
||||
},
|
||||
},
|
||||
wantLogLines: []string{
|
||||
@@ -1211,7 +1231,7 @@ func TestController(t *testing.T) {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *someJWTAuthenticatorSpecWithEveryOptionalValue,
|
||||
Spec: *someJWTAuthenticatorSpecWithManyOptionalValues,
|
||||
Status: authenticationv1alpha1.JWTAuthenticatorStatus{
|
||||
Conditions: allHappyConditionsSuccess(goodIssuer, frozenMetav1Now, 0),
|
||||
Phase: "Ready",
|
||||
@@ -1229,6 +1249,42 @@ func TestController(t *testing.T) {
|
||||
wantExtras: map[string][]string{"example.com/key-name": {"extra-value"}},
|
||||
wantNamesOfJWTAuthenticatorsInCache: []string{"test-name"},
|
||||
},
|
||||
{
|
||||
name: "Sync: JWTAuthenticator with usernameExpression and groupsExpression values: loop will complete successfully and update status conditions",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *someJWTAuthenticatorSpecWithUsernameAndGroupExpressions,
|
||||
},
|
||||
},
|
||||
wantLogLines: []string{
|
||||
fmt.Sprintf(`{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:<line>$jwtcachefiller.(*jwtCacheFillerController).updateStatus","message":"jwtauthenticator status successfully updated","jwtAuthenticator":"test-name","issuer":"%s","phase":"Ready"}`, goodIssuer),
|
||||
fmt.Sprintf(`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:<line>$jwtcachefiller.(*jwtCacheFillerController).syncIndividualJWTAuthenticator","message":"added or updated jwt authenticator in cache","jwtAuthenticator":"test-name","issuer":"%s","isOverwrite":false}`, goodIssuer),
|
||||
},
|
||||
wantActions: func() []coretesting.Action {
|
||||
updateStatusAction := coretesting.NewUpdateAction(jwtAuthenticatorsGVR, "", &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *someJWTAuthenticatorSpecWithUsernameAndGroupExpressions,
|
||||
Status: authenticationv1alpha1.JWTAuthenticatorStatus{
|
||||
Conditions: allHappyConditionsSuccess(goodIssuer, frozenMetav1Now, 0),
|
||||
Phase: "Ready",
|
||||
},
|
||||
})
|
||||
updateStatusAction.Subresource = "status"
|
||||
return []coretesting.Action{
|
||||
coretesting.NewListAction(jwtAuthenticatorsGVR, jwtAUthenticatorGVK, "", metav1.ListOptions{}),
|
||||
coretesting.NewWatchAction(jwtAuthenticatorsGVR, "", metav1.ListOptions{Watch: true}),
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
wantUsernameClaim: "otherUsernameClaim",
|
||||
wantGroupsClaim: "otherGroupsClaim",
|
||||
wantNamesOfJWTAuthenticatorsInCache: []string{"test-name"},
|
||||
},
|
||||
{
|
||||
name: "Sync: JWTAuthenticator with new spec.tls fields: loop will close previous instance of JWTAuthenticator and complete successfully and update status conditions",
|
||||
cache: func(t *testing.T, cache *authncache.Cache, wantClose bool) {
|
||||
@@ -2652,6 +2708,53 @@ func TestController(t *testing.T) {
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "newCachedJWTAuthenticator: validateAuthenticationConfiguration: when username and usernameExpression and/or groups and groupsExpression are both set: loop will fail sync, will write failed and unknown status conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
&authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *invalidClaimsMutualExclusiveRulesBothSetJWTAuthenticatorSpec,
|
||||
},
|
||||
},
|
||||
wantLogLines: []string{
|
||||
fmt.Sprintf(`{"level":"info","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:<line>$jwtcachefiller.(*jwtCacheFillerController).syncIndividualJWTAuthenticator","message":"invalid jwt authenticator","jwtAuthenticator":"test-name","issuer":"%s","removedFromCache":false}`, invalidClaimsMutualExclusiveRulesBothSetJWTAuthenticatorSpec.Issuer),
|
||||
fmt.Sprintf(`{"level":"debug","timestamp":"2099-08-08T13:57:36.123456Z","logger":"jwtcachefiller-controller","caller":"jwtcachefiller/jwtcachefiller.go:<line>$jwtcachefiller.(*jwtCacheFillerController).updateStatus","message":"jwtauthenticator status successfully updated","jwtAuthenticator":"test-name","issuer":"%s","phase":"Error"}`, invalidClaimsMutualExclusiveRulesBothSetJWTAuthenticatorSpec.Issuer),
|
||||
},
|
||||
wantActions: func() []coretesting.Action {
|
||||
updateStatusAction := coretesting.NewUpdateAction(jwtAuthenticatorsGVR, "", &authenticationv1alpha1.JWTAuthenticator{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-name",
|
||||
},
|
||||
Spec: *invalidClaimsMutualExclusiveRulesBothSetJWTAuthenticatorSpec,
|
||||
Status: authenticationv1alpha1.JWTAuthenticatorStatus{
|
||||
Conditions: conditionstestutil.Replace(
|
||||
allHappyConditionsSuccess(goodIssuer, frozenMetav1Now, 0),
|
||||
[]metav1.Condition{
|
||||
sadReadyCondition(frozenMetav1Now, 0),
|
||||
happyIssuerURLValid(frozenMetav1Now, 0),
|
||||
happyDiscoveryURLValid(frozenMetav1Now, 0),
|
||||
sadAuthenticatorValid(
|
||||
`could not initialize jwt authenticator: [claims.username: Invalid value: "": claim and expression can't both be set, claims.groups: Invalid value: "": claim and expression can't both be set]`,
|
||||
frozenMetav1Now,
|
||||
0,
|
||||
),
|
||||
happyJWKSURLValid(frozenMetav1Now, 0),
|
||||
happyJWKSFetch(frozenMetav1Now, 0),
|
||||
},
|
||||
),
|
||||
Phase: "Error",
|
||||
},
|
||||
})
|
||||
updateStatusAction.Subresource = "status"
|
||||
return []coretesting.Action{
|
||||
coretesting.NewListAction(jwtAuthenticatorsGVR, jwtAUthenticatorGVK, "", metav1.ListOptions{}),
|
||||
coretesting.NewWatchAction(jwtAuthenticatorsGVR, "", metav1.ListOptions{Watch: true}),
|
||||
updateStatusAction,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "newCachedJWTAuthenticator: when any claims.extra[].key contains an equals sign: loop will fail sync, will write failed and unknown status conditions, but will not enqueue a resync due to user config error",
|
||||
jwtAuthenticators: []runtime.Object{
|
||||
@@ -2903,6 +3006,15 @@ func TestController(t *testing.T) {
|
||||
cachedAuthenticator, ok := temp.(tokenAuthenticatorCloser)
|
||||
require.True(t, ok)
|
||||
|
||||
usernameClaimIsCelExpression := false
|
||||
if temp.(*cachedJWTAuthenticator).claims.UsernameExpression != "" {
|
||||
usernameClaimIsCelExpression = true
|
||||
}
|
||||
groupsClaimIsCelExpression := false
|
||||
if temp.(*cachedJWTAuthenticator).claims.GroupsExpression != "" {
|
||||
groupsClaimIsCelExpression = true
|
||||
}
|
||||
|
||||
// Schedule it to be closed at the end of the test.
|
||||
t.Cleanup(cachedAuthenticator.Close)
|
||||
|
||||
@@ -2930,13 +3042,19 @@ func TestController(t *testing.T) {
|
||||
group1,
|
||||
goodUsername,
|
||||
tt.wantUsernameClaim,
|
||||
usernameClaimIsCelExpression,
|
||||
tt.wantGroupsClaim,
|
||||
groupsClaimIsCelExpression,
|
||||
tt.wantExtras,
|
||||
goodIssuer,
|
||||
) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if test.skip != nil {
|
||||
test.skip(t) // give the test a chance to skip itself if it wants to
|
||||
}
|
||||
|
||||
wellKnownClaims := josejwt.Claims{
|
||||
Issuer: goodIssuer,
|
||||
Subject: goodSubject,
|
||||
@@ -3012,7 +3130,9 @@ func testTableForAuthenticateTokenTests(
|
||||
group1 string,
|
||||
goodUsername string,
|
||||
expectedUsernameClaim string,
|
||||
usernameClaimIsCelExpression bool,
|
||||
expectedGroupsClaim string,
|
||||
groupsClaimIsCelExpression bool,
|
||||
expectedExtras map[string][]string,
|
||||
issuer string,
|
||||
) []struct {
|
||||
@@ -3023,7 +3143,22 @@ func testTableForAuthenticateTokenTests(
|
||||
wantAuthenticated bool
|
||||
wantErr testutil.RequireErrorStringFunc
|
||||
distributedGroupsClaimURL string
|
||||
skip func(t *testing.T)
|
||||
} {
|
||||
expectedErrForBadTokenWithGroupsAsMap := func() testutil.RequireErrorStringFunc {
|
||||
if groupsClaimIsCelExpression {
|
||||
return testutil.WantExactErrorString(`oidc: error evaluating group claim expression: expression must return a string or a list of strings`)
|
||||
}
|
||||
return testutil.WantExactErrorString(`oidc: parse groups claim "` + expectedGroupsClaim + `": json: cannot unmarshal object into Go value of type string`)
|
||||
}
|
||||
|
||||
expectedErrForTokenDoesNotHaveUsernameClaim := func() testutil.RequireErrorStringFunc {
|
||||
if usernameClaimIsCelExpression {
|
||||
return testutil.WantMatchingErrorString(`oidc: error evaluating username claim expression: expression '.+' resulted in error: no such key: ` + expectedUsernameClaim)
|
||||
}
|
||||
return testutil.WantExactErrorString(`oidc: parse username claims "` + expectedUsernameClaim + `": claim not present`)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
jwtClaims func(wellKnownClaims *josejwt.Claims, groups *any, username *string)
|
||||
@@ -3032,6 +3167,7 @@ func testTableForAuthenticateTokenTests(
|
||||
wantAuthenticated bool
|
||||
wantErr testutil.RequireErrorStringFunc
|
||||
distributedGroupsClaimURL string
|
||||
skip func(t *testing.T)
|
||||
}{
|
||||
{
|
||||
name: "good token without groups and with EC signature",
|
||||
@@ -3085,13 +3221,23 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
},
|
||||
wantAuthenticated: true,
|
||||
skip: func(t *testing.T) {
|
||||
if groupsClaimIsCelExpression {
|
||||
t.Skip("skipping test because Kubernetes does not support using a CEL expression for groups mapping with distributed claims")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "distributed groups returns a 404",
|
||||
jwtClaims: func(claims *josejwt.Claims, groups *any, username *string) {
|
||||
},
|
||||
distributedGroupsClaimURL: issuer + "/not_found_claim_source",
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: while getting distributed claim "` + expectedGroupsClaim + `": error while getting distributed claim JWT: 404 Not Found`),
|
||||
wantErr: testutil.WantExactErrorString(`oidc: could not expand distributed claims: while getting distributed claim "` + expectedGroupsClaim + `": error while getting distributed claim JWT: 404 Not Found`),
|
||||
skip: func(t *testing.T) {
|
||||
if groupsClaimIsCelExpression {
|
||||
t.Skip("skipping test because Kubernetes does not support using a CEL expression for groups mapping with distributed claims")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "distributed groups doesn't return the right claim",
|
||||
@@ -3099,6 +3245,11 @@ func testTableForAuthenticateTokenTests(
|
||||
},
|
||||
distributedGroupsClaimURL: issuer + "/wrong_claim_source",
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: could not expand distributed claims: jwt returned by distributed claim endpoint "` + issuer + `/wrong_claim_source" did not contain claim: `),
|
||||
skip: func(t *testing.T) {
|
||||
if groupsClaimIsCelExpression {
|
||||
t.Skip("skipping test because Kubernetes does not support using a CEL expression for groups mapping with distributed claims")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "good token with groups as string",
|
||||
@@ -3132,7 +3283,7 @@ func testTableForAuthenticateTokenTests(
|
||||
jwtClaims: func(_ *josejwt.Claims, groups *any, username *string) {
|
||||
*groups = map[string]string{"not an array": "or a string"}
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: parse groups claim "` + expectedGroupsClaim + `": json: cannot unmarshal object into Go value of type string`),
|
||||
wantErr: expectedErrForBadTokenWithGroupsAsMap(),
|
||||
},
|
||||
{
|
||||
name: "bad token with wrong issuer",
|
||||
@@ -3147,14 +3298,14 @@ func testTableForAuthenticateTokenTests(
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Audience = nil
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \[\]`),
|
||||
wantErr: testutil.WantExactErrorString(`oidc: verify token: oidc: expected audience "some-audience" got []`),
|
||||
},
|
||||
{
|
||||
name: "bad token with wrong audience",
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
claims.Audience = []string{"wrong-audience"}
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: expected audience "some-audience" got \["wrong-audience"\]`),
|
||||
wantErr: testutil.WantExactErrorString(`oidc: verify token: oidc: expected audience "some-audience" got ["wrong-audience"]`),
|
||||
},
|
||||
{
|
||||
name: "bad token with nbf in the future",
|
||||
@@ -3182,7 +3333,7 @@ func testTableForAuthenticateTokenTests(
|
||||
jwtClaims: func(claims *josejwt.Claims, _ *any, username *string) {
|
||||
*username = ""
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: parse username claims "` + expectedUsernameClaim + `": claim not present`),
|
||||
wantErr: expectedErrForTokenDoesNotHaveUsernameClaim(),
|
||||
},
|
||||
{
|
||||
name: "signing key is wrong",
|
||||
@@ -3192,7 +3343,7 @@ func testTableForAuthenticateTokenTests(
|
||||
require.NoError(t, err)
|
||||
*algo = jose.ES256
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: failed to verify signature: failed to verify id token signature`),
|
||||
wantErr: testutil.WantExactErrorString(`oidc: verify token: failed to verify signature: failed to verify id token signature`),
|
||||
},
|
||||
{
|
||||
name: "signing algo is unsupported",
|
||||
@@ -3202,7 +3353,7 @@ func testTableForAuthenticateTokenTests(
|
||||
require.NoError(t, err)
|
||||
*algo = jose.ES384
|
||||
},
|
||||
wantErr: testutil.WantMatchingErrorString(`oidc: verify token: oidc: id token signed with unsupported algorithm, expected \["RS256" "ES256"\] got "ES384"`),
|
||||
wantErr: testutil.WantExactErrorString(`oidc: verify token: oidc: id token signed with unsupported algorithm, expected ["RS256" "ES256"] got "ES384"`),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user