Nest claim configs one level deeper in JWTAuthenticatorSpec

Signed-off-by: Margo Crawford <margaretc@vmware.com>
This commit is contained in:
Ryan Richard 2020-12-16 09:42:19 -08:00 committed by Margo Crawford
parent 40c6a67631
commit dcb19150fc
17 changed files with 253 additions and 91 deletions

View File

@ -27,21 +27,30 @@ type JWTAuthenticatorSpec struct {
// +kubebuilder:validation:MinLength=1
Audience string `json:"audience"`
// UsernameClaim is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// Claims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
// +optional
UsernameClaim string `json:"username_claim"`
// GroupsClaim is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
GroupsClaim string `json:"groups_claim"`
Claims JWTTokenClaims `json:"claims"`
// TLS configuration for communicating with the OIDC provider.
// +optional
TLS *TLSSpec `json:"tls,omitempty"`
}
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
type JWTTokenClaims struct {
// Groups is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
Groups string `json:"groups"`
// Username is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// +optional
Username string `json:"username"`
}
// JWTAuthenticator describes the configuration of a JWT authenticator.
//
// Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid

View File

@ -51,11 +51,21 @@ spec:
description: Audience is the required value of the "aud" JWT claim.
minLength: 1
type: string
groups_claim:
description: GroupsClaim is the name of the claim which should be
read to extract the user's group membership from the JWT token.
When not specified, it will default to "groups".
type: string
claims:
description: Claims allows customization of the claims that will be
mapped to user identity for Kubernetes access.
properties:
groups:
description: Groups is the name of the claim which should be read
to extract the user's group membership from the JWT token. When
not specified, it will default to "groups".
type: string
username:
description: Username is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
type: object
issuer:
description: Issuer is the OIDC issuer URL that will be used to discover
public signing keys. Issuer is also used to validate the "iss" JWT
@ -71,11 +81,6 @@ spec:
If omitted, a default set of system roots will be trusted.
type: string
type: object
username_claim:
description: UsernameClaim is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
required:
- audience
- issuer

View File

@ -92,8 +92,7 @@ Spec for configuring a JWT authenticator.
| Field | Description
| *`issuer`* __string__ | Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is also used to validate the "iss" JWT claim.
| *`audience`* __string__ | Audience is the required value of the "aud" JWT claim.
| *`username_claim`* __string__ | UsernameClaim is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
| *`groups_claim`* __string__ | GroupsClaim is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`claims`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-jwttokenclaims[$$JWTTokenClaims$$]__ | Claims allows customization of the claims that will be mapped to user identity for Kubernetes access.
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS configuration for communicating with the OIDC provider.
|===
@ -115,6 +114,24 @@ Status of a JWT authenticator.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-jwttokenclaims"]
==== JWTTokenClaims
JWTTokenClaims allows customization of the claims that will be mapped to user identity for Kubernetes access.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-jwtauthenticatorspec[$$JWTAuthenticatorSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`groups`* __string__ | Groups is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`username`* __string__ | Username is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-17-apis-concierge-authentication-v1alpha1-tlsspec"]
==== TLSSpec

View File

@ -27,21 +27,30 @@ type JWTAuthenticatorSpec struct {
// +kubebuilder:validation:MinLength=1
Audience string `json:"audience"`
// UsernameClaim is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// Claims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
// +optional
UsernameClaim string `json:"username_claim"`
// GroupsClaim is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
GroupsClaim string `json:"groups_claim"`
Claims JWTTokenClaims `json:"claims"`
// TLS configuration for communicating with the OIDC provider.
// +optional
TLS *TLSSpec `json:"tls,omitempty"`
}
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
type JWTTokenClaims struct {
// Groups is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
Groups string `json:"groups"`
// Username is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// +optional
Username string `json:"username"`
}
// JWTAuthenticator describes the configuration of a JWT authenticator.
//
// Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid

View File

@ -92,6 +92,7 @@ func (in *JWTAuthenticatorList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTAuthenticatorSpec) DeepCopyInto(out *JWTAuthenticatorSpec) {
*out = *in
out.Claims = in.Claims
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLSSpec)
@ -133,6 +134,22 @@ func (in *JWTAuthenticatorStatus) DeepCopy() *JWTAuthenticatorStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTTokenClaims) DeepCopyInto(out *JWTTokenClaims) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTTokenClaims.
func (in *JWTTokenClaims) DeepCopy() *JWTTokenClaims {
if in == nil {
return nil
}
out := new(JWTTokenClaims)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSSpec) DeepCopyInto(out *TLSSpec) {
*out = *in

View File

@ -51,11 +51,21 @@ spec:
description: Audience is the required value of the "aud" JWT claim.
minLength: 1
type: string
groups_claim:
description: GroupsClaim is the name of the claim which should be
read to extract the user's group membership from the JWT token.
When not specified, it will default to "groups".
type: string
claims:
description: Claims allows customization of the claims that will be
mapped to user identity for Kubernetes access.
properties:
groups:
description: Groups is the name of the claim which should be read
to extract the user's group membership from the JWT token. When
not specified, it will default to "groups".
type: string
username:
description: Username is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
type: object
issuer:
description: Issuer is the OIDC issuer URL that will be used to discover
public signing keys. Issuer is also used to validate the "iss" JWT
@ -71,11 +81,6 @@ spec:
If omitted, a default set of system roots will be trusted.
type: string
type: object
username_claim:
description: UsernameClaim is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
required:
- audience
- issuer

View File

@ -92,8 +92,7 @@ Spec for configuring a JWT authenticator.
| Field | Description
| *`issuer`* __string__ | Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is also used to validate the "iss" JWT claim.
| *`audience`* __string__ | Audience is the required value of the "aud" JWT claim.
| *`username_claim`* __string__ | UsernameClaim is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
| *`groups_claim`* __string__ | GroupsClaim is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`claims`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-concierge-authentication-v1alpha1-jwttokenclaims[$$JWTTokenClaims$$]__ | Claims allows customization of the claims that will be mapped to user identity for Kubernetes access.
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-concierge-authentication-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS configuration for communicating with the OIDC provider.
|===
@ -115,6 +114,24 @@ Status of a JWT authenticator.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-concierge-authentication-v1alpha1-jwttokenclaims"]
==== JWTTokenClaims
JWTTokenClaims allows customization of the claims that will be mapped to user identity for Kubernetes access.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-concierge-authentication-v1alpha1-jwtauthenticatorspec[$$JWTAuthenticatorSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`groups`* __string__ | Groups is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`username`* __string__ | Username is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-18-apis-concierge-authentication-v1alpha1-tlsspec"]
==== TLSSpec

View File

@ -27,21 +27,30 @@ type JWTAuthenticatorSpec struct {
// +kubebuilder:validation:MinLength=1
Audience string `json:"audience"`
// UsernameClaim is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// Claims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
// +optional
UsernameClaim string `json:"username_claim"`
// GroupsClaim is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
GroupsClaim string `json:"groups_claim"`
Claims JWTTokenClaims `json:"claims"`
// TLS configuration for communicating with the OIDC provider.
// +optional
TLS *TLSSpec `json:"tls,omitempty"`
}
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
type JWTTokenClaims struct {
// Groups is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
Groups string `json:"groups"`
// Username is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// +optional
Username string `json:"username"`
}
// JWTAuthenticator describes the configuration of a JWT authenticator.
//
// Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid

View File

@ -92,6 +92,7 @@ func (in *JWTAuthenticatorList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTAuthenticatorSpec) DeepCopyInto(out *JWTAuthenticatorSpec) {
*out = *in
out.Claims = in.Claims
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLSSpec)
@ -133,6 +134,22 @@ func (in *JWTAuthenticatorStatus) DeepCopy() *JWTAuthenticatorStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTTokenClaims) DeepCopyInto(out *JWTTokenClaims) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTTokenClaims.
func (in *JWTTokenClaims) DeepCopy() *JWTTokenClaims {
if in == nil {
return nil
}
out := new(JWTTokenClaims)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSSpec) DeepCopyInto(out *TLSSpec) {
*out = *in

View File

@ -51,11 +51,21 @@ spec:
description: Audience is the required value of the "aud" JWT claim.
minLength: 1
type: string
groups_claim:
description: GroupsClaim is the name of the claim which should be
read to extract the user's group membership from the JWT token.
When not specified, it will default to "groups".
type: string
claims:
description: Claims allows customization of the claims that will be
mapped to user identity for Kubernetes access.
properties:
groups:
description: Groups is the name of the claim which should be read
to extract the user's group membership from the JWT token. When
not specified, it will default to "groups".
type: string
username:
description: Username is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
type: object
issuer:
description: Issuer is the OIDC issuer URL that will be used to discover
public signing keys. Issuer is also used to validate the "iss" JWT
@ -71,11 +81,6 @@ spec:
If omitted, a default set of system roots will be trusted.
type: string
type: object
username_claim:
description: UsernameClaim is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
required:
- audience
- issuer

View File

@ -92,8 +92,7 @@ Spec for configuring a JWT authenticator.
| Field | Description
| *`issuer`* __string__ | Issuer is the OIDC issuer URL that will be used to discover public signing keys. Issuer is also used to validate the "iss" JWT claim.
| *`audience`* __string__ | Audience is the required value of the "aud" JWT claim.
| *`username_claim`* __string__ | UsernameClaim is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
| *`groups_claim`* __string__ | GroupsClaim is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`claims`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwttokenclaims[$$JWTTokenClaims$$]__ | Claims allows customization of the claims that will be mapped to user identity for Kubernetes access.
| *`tls`* __xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-tlsspec[$$TLSSpec$$]__ | TLS configuration for communicating with the OIDC provider.
|===
@ -115,6 +114,24 @@ Status of a JWT authenticator.
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwttokenclaims"]
==== JWTTokenClaims
JWTTokenClaims allows customization of the claims that will be mapped to user identity for Kubernetes access.
.Appears In:
****
- xref:{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-jwtauthenticatorspec[$$JWTAuthenticatorSpec$$]
****
[cols="25a,75a", options="header"]
|===
| Field | Description
| *`groups`* __string__ | Groups is the name of the claim which should be read to extract the user's group membership from the JWT token. When not specified, it will default to "groups".
| *`username`* __string__ | Username is the name of the claim which should be read to extract the username from the JWT token. When not specified, it will default to "username".
|===
[id="{anchor_prefix}-go-pinniped-dev-generated-1-19-apis-concierge-authentication-v1alpha1-tlsspec"]
==== TLSSpec

View File

@ -27,21 +27,30 @@ type JWTAuthenticatorSpec struct {
// +kubebuilder:validation:MinLength=1
Audience string `json:"audience"`
// UsernameClaim is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// Claims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
// +optional
UsernameClaim string `json:"username_claim"`
// GroupsClaim is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
GroupsClaim string `json:"groups_claim"`
Claims JWTTokenClaims `json:"claims"`
// TLS configuration for communicating with the OIDC provider.
// +optional
TLS *TLSSpec `json:"tls,omitempty"`
}
// JWTTokenClaims allows customization of the claims that will be mapped to user identity
// for Kubernetes access.
type JWTTokenClaims struct {
// Groups is the name of the claim which should be read to extract the user's
// group membership from the JWT token. When not specified, it will default to "groups".
// +optional
Groups string `json:"groups"`
// Username is the name of the claim which should be read to extract the
// username from the JWT token. When not specified, it will default to "username".
// +optional
Username string `json:"username"`
}
// JWTAuthenticator describes the configuration of a JWT authenticator.
//
// Upon receiving a signed JWT, a JWTAuthenticator will performs some validation on it (e.g., valid

View File

@ -92,6 +92,7 @@ func (in *JWTAuthenticatorList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTAuthenticatorSpec) DeepCopyInto(out *JWTAuthenticatorSpec) {
*out = *in
out.Claims = in.Claims
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLSSpec)
@ -133,6 +134,22 @@ func (in *JWTAuthenticatorStatus) DeepCopy() *JWTAuthenticatorStatus {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JWTTokenClaims) DeepCopyInto(out *JWTTokenClaims) {
*out = *in
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTTokenClaims.
func (in *JWTTokenClaims) DeepCopy() *JWTTokenClaims {
if in == nil {
return nil
}
out := new(JWTTokenClaims)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLSSpec) DeepCopyInto(out *TLSSpec) {
*out = *in

View File

@ -51,11 +51,21 @@ spec:
description: Audience is the required value of the "aud" JWT claim.
minLength: 1
type: string
groups_claim:
description: GroupsClaim is the name of the claim which should be
read to extract the user's group membership from the JWT token.
When not specified, it will default to "groups".
type: string
claims:
description: Claims allows customization of the claims that will be
mapped to user identity for Kubernetes access.
properties:
groups:
description: Groups is the name of the claim which should be read
to extract the user's group membership from the JWT token. When
not specified, it will default to "groups".
type: string
username:
description: Username is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
type: object
issuer:
description: Issuer is the OIDC issuer URL that will be used to discover
public signing keys. Issuer is also used to validate the "iss" JWT
@ -71,11 +81,6 @@ spec:
If omitted, a default set of system roots will be trusted.
type: string
type: object
username_claim:
description: UsernameClaim is the name of the claim which should be
read to extract the username from the JWT token. When not specified,
it will default to "username".
type: string
required:
- audience
- issuer

View File

@ -169,11 +169,11 @@ func newJWTAuthenticator(spec *auth1alpha1.JWTAuthenticatorSpec) (*jwtAuthentica
caFile = temp.Name()
}
usernameClaim := spec.UsernameClaim
usernameClaim := spec.Claims.Username
if usernameClaim == "" {
usernameClaim = defaultUsernameClaim
}
groupsClaim := spec.GroupsClaim
groupsClaim := spec.Claims.Groups
if groupsClaim == "" {
groupsClaim = defaultGroupsClaim
}

View File

@ -90,16 +90,20 @@ func TestController(t *testing.T) {
TLS: tlsSpecFromTLSConfig(server.TLS),
}
someJWTAuthenticatorSpecWithUsernameClaim := &auth1alpha1.JWTAuthenticatorSpec{
Issuer: goodIssuer,
Audience: goodAudience,
TLS: tlsSpecFromTLSConfig(server.TLS),
UsernameClaim: "my-custom-username-claim",
Issuer: goodIssuer,
Audience: goodAudience,
TLS: tlsSpecFromTLSConfig(server.TLS),
Claims: auth1alpha1.JWTTokenClaims{
Username: "my-custom-username-claim",
},
}
someJWTAuthenticatorSpecWithGroupsClaim := &auth1alpha1.JWTAuthenticatorSpec{
Issuer: goodIssuer,
Audience: goodAudience,
TLS: tlsSpecFromTLSConfig(server.TLS),
GroupsClaim: "my-custom-groups-claim",
Issuer: goodIssuer,
Audience: goodAudience,
TLS: tlsSpecFromTLSConfig(server.TLS),
Claims: auth1alpha1.JWTTokenClaims{
Groups: "my-custom-groups-claim",
},
}
otherJWTAuthenticatorSpec := &auth1alpha1.JWTAuthenticatorSpec{
Issuer: "https://some-other-issuer.com",
@ -170,7 +174,7 @@ func TestController(t *testing.T) {
`jwtcachefiller-controller "level"=0 "msg"="added new jwt authenticator" "issuer"="` + goodIssuer + `" "jwtAuthenticator"={"name":"test-name","namespace":"test-namespace"}`,
},
wantCacheEntries: 1,
wantUsernameClaim: someJWTAuthenticatorSpecWithUsernameClaim.UsernameClaim,
wantUsernameClaim: someJWTAuthenticatorSpecWithUsernameClaim.Claims.Username,
runTestsOnResultingAuthenticator: true,
},
{
@ -189,7 +193,7 @@ func TestController(t *testing.T) {
`jwtcachefiller-controller "level"=0 "msg"="added new jwt authenticator" "issuer"="` + goodIssuer + `" "jwtAuthenticator"={"name":"test-name","namespace":"test-namespace"}`,
},
wantCacheEntries: 1,
wantGroupsClaim: someJWTAuthenticatorSpecWithGroupsClaim.GroupsClaim,
wantGroupsClaim: someJWTAuthenticatorSpecWithGroupsClaim.Claims.Groups,
runTestsOnResultingAuthenticator: true,
},
{

View File

@ -182,7 +182,7 @@ func CreateTestJWTAuthenticatorForCLIUpstream(ctx context.Context, t *testing.T)
Audience: testEnv.CLITestUpstream.ClientID,
// The default UsernameClaim is "username" but the upstreams that we use for
// integration tests won't necessarily have that claim, so use "sub" here.
UsernameClaim: "sub",
Claims: auth1alpha1.JWTTokenClaims{Username: "sub"},
}
// If the test upstream does not have a CA bundle specified, then don't configure one in the
// JWTAuthenticator. Leaving TLSSpec set to nil will result in OIDC discovery using the OS's root