Merge pull request #62692 from mikedanese/trev2

authn: extend authenticator.Token to support audience validation
This commit is contained in:
k8s-ci-robot 2018-11-16 20:27:25 -08:00 committed by GitHub
commit f38cc95505
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 758 additions and 161 deletions

View File

@ -80871,6 +80871,13 @@
"io.k8s.api.authentication.v1.TokenReviewSpec": {
"description": "TokenReviewSpec is a description of the token authentication request.",
"properties": {
"audiences": {
"description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
"type": "array",
"items": {
"type": "string"
}
},
"token": {
"description": "Token is the opaque bearer token.",
"type": "string"
@ -80880,6 +80887,13 @@
"io.k8s.api.authentication.v1.TokenReviewStatus": {
"description": "TokenReviewStatus is the result of the token authentication request.",
"properties": {
"audiences": {
"description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"type": "array",
"items": {
"type": "string"
}
},
"authenticated": {
"description": "Authenticated indicates that the token was associated with a known user.",
"type": "boolean"
@ -80961,6 +80975,13 @@
"io.k8s.api.authentication.v1beta1.TokenReviewSpec": {
"description": "TokenReviewSpec is a description of the token authentication request.",
"properties": {
"audiences": {
"description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
"type": "array",
"items": {
"type": "string"
}
},
"token": {
"description": "Token is the opaque bearer token.",
"type": "string"
@ -80970,6 +80991,13 @@
"io.k8s.api.authentication.v1beta1.TokenReviewStatus": {
"description": "TokenReviewStatus is the result of the token authentication request.",
"properties": {
"audiences": {
"description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"type": "array",
"items": {
"type": "string"
}
},
"authenticated": {
"description": "Authenticated indicates that the token was associated with a known user.",
"type": "boolean"

View File

@ -395,6 +395,13 @@
"token": {
"type": "string",
"description": "Token is the opaque bearer token."
},
"audiences": {
"type": "array",
"items": {
"type": "string"
},
"description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver."
}
}
},
@ -410,6 +417,13 @@
"$ref": "v1.UserInfo",
"description": "User is the UserInfo associated with the provided token."
},
"audiences": {
"type": "array",
"items": {
"type": "string"
},
"description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server."
},
"error": {
"type": "string",
"description": "Error indicates that the token couldn't be checked"

View File

@ -395,6 +395,13 @@
"token": {
"type": "string",
"description": "Token is the opaque bearer token."
},
"audiences": {
"type": "array",
"items": {
"type": "string"
},
"description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver."
}
}
},
@ -410,6 +417,13 @@
"$ref": "v1beta1.UserInfo",
"description": "User is the UserInfo associated with the provided token."
},
"audiences": {
"type": "array",
"items": {
"type": "string"
},
"description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server."
},
"error": {
"type": "string",
"description": "Error indicates that the token couldn't be checked"

View File

@ -1053,6 +1053,13 @@ When an object is created, the system will populate this list with the current s
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">audiences</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -1095,6 +1102,13 @@ When an object is created, the system will populate this list with the current s
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">audiences</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token&#8217;s audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is "true", the token is valid against the audience of the Kubernetes API server.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">error</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Error indicates that the token couldn&#8217;t be checked</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>

View File

@ -567,6 +567,13 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">audiences</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody>
</table>
@ -1060,6 +1067,13 @@ When an object is created, the system will populate this list with the current s
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">audiences</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token&#8217;s audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is "true", the token is valid against the audience of the Kubernetes API server.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">string array</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">error</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Error indicates that the token couldn&#8217;t be checked</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>

View File

@ -59,6 +59,12 @@ type TokenReview struct {
type TokenReviewSpec struct {
// Token is the opaque bearer token.
Token string
// Audiences is a list of the identifiers that the resource server presented
// with the token identifies as. Audience-aware token authenticators will
// verify that the token was intended for at least one of the audiences in
// this list. If no audiences are provided, the audience will default to the
// audience of the Kubernetes apiserver.
Audiences []string
}
// TokenReviewStatus is the result of the token authentication request.
@ -68,6 +74,16 @@ type TokenReviewStatus struct {
Authenticated bool
// User is the UserInfo associated with the provided token.
User UserInfo
// Audiences are audience identifiers chosen by the authenticator that are
// compatible with both the TokenReview and token. An identifier is any
// identifier in the intersection of the TokenReviewSpec audiences and the
// token's audiences. A client of the TokenReview API that sets the
// spec.audiences field should validate that a compatible audience identifier
// is returned in the status.audiences field to ensure that the TokenReview
// server is audience aware. If a TokenReview returns an empty
// status.audience field where status.authenticated is "true", the token is
// valid against the audience of the Kubernetes API server.
Audiences []string
// Error indicates that the token couldn't be checked
Error string
}

View File

@ -263,6 +263,7 @@ func Convert_authentication_TokenReview_To_v1_TokenReview(in *authentication.Tok
func autoConvert_v1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1.TokenReviewSpec, out *authentication.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@ -273,6 +274,7 @@ func Convert_v1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1.TokenRe
func autoConvert_authentication_TokenReviewSpec_To_v1_TokenReviewSpec(in *authentication.TokenReviewSpec, out *v1.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@ -286,6 +288,7 @@ func autoConvert_v1_TokenReviewStatus_To_authentication_TokenReviewStatus(in *v1
if err := Convert_v1_UserInfo_To_authentication_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
@ -300,6 +303,7 @@ func autoConvert_authentication_TokenReviewStatus_To_v1_TokenReviewStatus(in *au
if err := Convert_authentication_UserInfo_To_v1_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}

View File

@ -113,6 +113,7 @@ func Convert_authentication_TokenReview_To_v1beta1_TokenReview(in *authenticatio
func autoConvert_v1beta1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1beta1.TokenReviewSpec, out *authentication.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@ -123,6 +124,7 @@ func Convert_v1beta1_TokenReviewSpec_To_authentication_TokenReviewSpec(in *v1bet
func autoConvert_authentication_TokenReviewSpec_To_v1beta1_TokenReviewSpec(in *authentication.TokenReviewSpec, out *v1beta1.TokenReviewSpec, s conversion.Scope) error {
out.Token = in.Token
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
return nil
}
@ -136,6 +138,7 @@ func autoConvert_v1beta1_TokenReviewStatus_To_authentication_TokenReviewStatus(i
if err := Convert_v1beta1_UserInfo_To_authentication_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}
@ -150,6 +153,7 @@ func autoConvert_authentication_TokenReviewStatus_To_v1beta1_TokenReviewStatus(i
if err := Convert_authentication_UserInfo_To_v1beta1_UserInfo(&in.User, &out.User, s); err != nil {
return err
}
out.Audiences = *(*[]string)(unsafe.Pointer(&in.Audiences))
out.Error = in.Error
return nil
}

View File

@ -136,7 +136,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -162,6 +162,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
@ -179,6 +184,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}

View File

@ -179,7 +179,7 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er
tokenAuthenticators = append(tokenAuthenticators, oidcAuth)
}
if len(config.WebhookTokenAuthnConfigFile) > 0 {
webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL)
webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL, config.APIAudiences)
if err != nil {
return nil, nil, err
}
@ -318,8 +318,8 @@ func newAuthenticatorFromClientCAFile(clientCAFile string) (authenticator.Reques
return x509.New(opts, x509.CommonNameUserConversion), nil
}
func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration) (authenticator.Token, error) {
webhookTokenAuthenticator, err := webhook.New(webhookConfigFile)
func newWebhookTokenAuthenticator(webhookConfigFile string, ttl time.Duration, implicitAuds authenticator.Audiences) (authenticator.Token, error) {
webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, implicitAuds)
if err != nil {
return nil, err
}

View File

@ -335,7 +335,7 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
// handlers that we have.
restStorageProviders := []RESTStorageProvider{
auditregistrationrest.RESTStorageProvider{},
authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator},
authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
autoscalingrest.RESTStorageProvider{},
batchrest.RESTStorageProvider{},

View File

@ -31,6 +31,7 @@ import (
type RESTStorageProvider struct {
Authenticator authenticator.Request
APIAudiences authenticator.Audiences
}
func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, bool) {
@ -56,7 +57,7 @@ func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorag
func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
storage := map[string]rest.Storage{}
// tokenreviews
tokenReviewStorage := tokenreview.NewREST(p.Authenticator)
tokenReviewStorage := tokenreview.NewREST(p.Authenticator, p.APIAudiences)
storage["tokenreviews"] = tokenReviewStorage
return storage
@ -65,7 +66,7 @@ func (p RESTStorageProvider) v1beta1Storage(apiResourceConfigSource serverstorag
func (p RESTStorageProvider) v1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
storage := map[string]rest.Storage{}
// tokenreviews
tokenReviewStorage := tokenreview.NewREST(p.Authenticator)
tokenReviewStorage := tokenreview.NewREST(p.Authenticator, p.APIAudiences)
storage["tokenreviews"] = tokenReviewStorage
return storage

View File

@ -17,6 +17,7 @@ go_library(
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/rest:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
],
)

View File

@ -18,6 +18,7 @@ package tokenreview
import (
"context"
"errors"
"fmt"
"net/http"
@ -27,15 +28,22 @@ import (
"k8s.io/apiserver/pkg/authentication/authenticator"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/apis/authentication"
)
var badAuthenticatorAuds = apierrors.NewInternalError(errors.New("error validating audiences"))
type REST struct {
tokenAuthenticator authenticator.Request
apiAudiences []string
}
func NewREST(tokenAuthenticator authenticator.Request) *REST {
return &REST{tokenAuthenticator: tokenAuthenticator}
func NewREST(tokenAuthenticator authenticator.Request, apiAudiences []string) *REST {
return &REST{
tokenAuthenticator: tokenAuthenticator,
apiAudiences: apiAudiences,
}
}
func (r *REST) NamespaceScoped() bool {
@ -68,14 +76,24 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
fakeReq := &http.Request{Header: http.Header{}}
fakeReq.Header.Add("Authorization", "Bearer "+tokenReview.Spec.Token)
auds := tokenReview.Spec.Audiences
if len(auds) == 0 {
auds = r.apiAudiences
}
if len(auds) > 0 {
fakeReq = fakeReq.WithContext(authenticator.WithAudiences(fakeReq.Context(), auds))
}
resp, ok, err := r.tokenAuthenticator.AuthenticateRequest(fakeReq)
tokenReview.Status.Authenticated = ok
if err != nil {
tokenReview.Status.Error = err.Error()
}
// TODO(mikedanese): verify the response audience matches one of apiAuds if
// non-empty
if len(auds) > 0 && resp != nil && len(authenticator.Audiences(auds).Intersect(resp.Audiences)) == 0 {
klog.Errorf("error validating audience. want=%q got=%q", auds, resp.Audiences)
return nil, badAuthenticatorAuds
}
if resp != nil && resp.User != nil {
tokenReview.Status.User = authentication.UserInfo{
@ -87,6 +105,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
for k, v := range resp.User.GetExtra() {
tokenReview.Status.User.Extra[k] = authentication.ExtraValue(v)
}
tokenReview.Status.Audiences = resp.Audiences
}
return tokenReview, nil

View File

@ -355,6 +355,21 @@ func (m *TokenReviewSpec) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Token)))
i += copy(dAtA[i:], m.Token)
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
dAtA[i] = 0x12
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@ -393,6 +408,21 @@ func (m *TokenReviewStatus) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Error)))
i += copy(dAtA[i:], m.Error)
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
dAtA[i] = 0x22
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@ -561,6 +591,12 @@ func (m *TokenReviewSpec) Size() (n int) {
_ = l
l = len(m.Token)
n += 1 + l + sovGenerated(uint64(l))
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
@ -572,6 +608,12 @@ func (m *TokenReviewStatus) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Error)
n += 1 + l + sovGenerated(uint64(l))
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
@ -679,6 +721,7 @@ func (this *TokenReviewSpec) String() string {
}
s := strings.Join([]string{`&TokenReviewSpec{`,
`Token:` + fmt.Sprintf("%v", this.Token) + `,`,
`Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@ -691,6 +734,7 @@ func (this *TokenReviewStatus) String() string {
`Authenticated:` + fmt.Sprintf("%v", this.Authenticated) + `,`,
`User:` + strings.Replace(strings.Replace(this.User.String(), "UserInfo", "UserInfo", 1), `&`, ``, 1) + `,`,
`Error:` + fmt.Sprintf("%v", this.Error) + `,`,
`Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@ -1550,6 +1594,35 @@ func (m *TokenReviewSpec) Unmarshal(dAtA []byte) error {
}
m.Token = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -1679,6 +1752,35 @@ func (m *TokenReviewStatus) Unmarshal(dAtA []byte) error {
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -2070,61 +2172,62 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 892 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x8f, 0xdb, 0x44,
0x14, 0x8e, 0xf3, 0x63, 0xb5, 0x99, 0x74, 0x97, 0xdd, 0x29, 0x95, 0xa2, 0x05, 0xec, 0x60, 0x24,
0x14, 0x01, 0xb5, 0x9b, 0x08, 0x95, 0xaa, 0x48, 0x48, 0x6b, 0x36, 0x82, 0x08, 0x41, 0xab, 0x69,
0x77, 0x41, 0x9c, 0x98, 0xd8, 0x6f, 0xb3, 0x26, 0x78, 0x6c, 0xec, 0x71, 0x68, 0x6e, 0xfd, 0x13,
0x38, 0x82, 0xc4, 0x81, 0x3f, 0x02, 0x89, 0x23, 0xd7, 0x3d, 0x56, 0x9c, 0x7a, 0x40, 0x11, 0x6b,
0xfe, 0x05, 0x4e, 0x9c, 0xd0, 0x8c, 0x67, 0xe3, 0xfc, 0xd8, 0x4d, 0x73, 0xea, 0x2d, 0xf3, 0xde,
0xf7, 0xbe, 0x79, 0xef, 0x9b, 0x2f, 0xcf, 0xa8, 0x37, 0xba, 0x97, 0x58, 0x7e, 0x68, 0x8f, 0xd2,
0x01, 0xc4, 0x0c, 0x38, 0x24, 0xf6, 0x18, 0x98, 0x17, 0xc6, 0xb6, 0x4a, 0xd0, 0xc8, 0xb7, 0x69,
0xca, 0xcf, 0x80, 0x71, 0xdf, 0xa5, 0xdc, 0x0f, 0x99, 0x3d, 0xee, 0xd8, 0x43, 0x60, 0x10, 0x53,
0x0e, 0x9e, 0x15, 0xc5, 0x21, 0x0f, 0xf1, 0xeb, 0x39, 0xda, 0xa2, 0x91, 0x6f, 0x2d, 0xa2, 0xad,
0x71, 0xe7, 0xe0, 0xf6, 0xd0, 0xe7, 0x67, 0xe9, 0xc0, 0x72, 0xc3, 0xc0, 0x1e, 0x86, 0xc3, 0xd0,
0x96, 0x45, 0x83, 0xf4, 0x54, 0x9e, 0xe4, 0x41, 0xfe, 0xca, 0xc9, 0x0e, 0xde, 0x2f, 0xae, 0x0e,
0xa8, 0x7b, 0xe6, 0x33, 0x88, 0x27, 0x76, 0x34, 0x1a, 0x8a, 0x40, 0x62, 0x07, 0xc0, 0xe9, 0x15,
0x2d, 0x1c, 0xd8, 0xd7, 0x55, 0xc5, 0x29, 0xe3, 0x7e, 0x00, 0x2b, 0x05, 0x77, 0x5f, 0x54, 0x90,
0xb8, 0x67, 0x10, 0xd0, 0xe5, 0x3a, 0xf3, 0x4f, 0x0d, 0xbd, 0xea, 0x84, 0x29, 0xf3, 0x1e, 0x0c,
0xbe, 0x05, 0x97, 0x13, 0x38, 0x85, 0x18, 0x98, 0x0b, 0xb8, 0x85, 0xaa, 0x23, 0x9f, 0x79, 0x4d,
0xad, 0xa5, 0xb5, 0xeb, 0xce, 0x8d, 0xf3, 0xa9, 0x51, 0xca, 0xa6, 0x46, 0xf5, 0x33, 0x9f, 0x79,
0x44, 0x66, 0x70, 0x17, 0x21, 0xfa, 0xb0, 0x7f, 0x02, 0x71, 0xe2, 0x87, 0xac, 0x59, 0x96, 0x38,
0xac, 0x70, 0xe8, 0x70, 0x96, 0x21, 0x73, 0x28, 0xc1, 0xca, 0x68, 0x00, 0xcd, 0xca, 0x22, 0xeb,
0x17, 0x34, 0x00, 0x22, 0x33, 0xd8, 0x41, 0x95, 0xb4, 0x7f, 0xd4, 0xac, 0x4a, 0xc0, 0x1d, 0x05,
0xa8, 0x1c, 0xf7, 0x8f, 0xfe, 0x9b, 0x1a, 0x6f, 0x5e, 0x37, 0x24, 0x9f, 0x44, 0x90, 0x58, 0xc7,
0xfd, 0x23, 0x22, 0x8a, 0xcd, 0x0f, 0x10, 0xea, 0x3d, 0xe1, 0x31, 0x3d, 0xa1, 0xdf, 0xa5, 0x80,
0x0d, 0x54, 0xf3, 0x39, 0x04, 0x49, 0x53, 0x6b, 0x55, 0xda, 0x75, 0xa7, 0x9e, 0x4d, 0x8d, 0x5a,
0x5f, 0x04, 0x48, 0x1e, 0xbf, 0xbf, 0xfd, 0xd3, 0xaf, 0x46, 0xe9, 0xe9, 0x5f, 0xad, 0x92, 0xf9,
0x4b, 0x19, 0xdd, 0x78, 0x1c, 0x8e, 0x80, 0x11, 0xf8, 0x3e, 0x85, 0x84, 0xe3, 0x6f, 0xd0, 0xb6,
0x78, 0x22, 0x8f, 0x72, 0x2a, 0x95, 0x68, 0x74, 0xef, 0x58, 0x85, 0x3b, 0x66, 0x4d, 0x58, 0xd1,
0x68, 0x28, 0x02, 0x89, 0x25, 0xd0, 0xd6, 0xb8, 0x63, 0xe5, 0x72, 0x7e, 0x0e, 0x9c, 0x16, 0x9a,
0x14, 0x31, 0x32, 0x63, 0xc5, 0x0f, 0x51, 0x35, 0x89, 0xc0, 0x95, 0xfa, 0x35, 0xba, 0x96, 0xb5,
0xce, 0x7b, 0xd6, 0x7c, 0x6f, 0x8f, 0x22, 0x70, 0x0b, 0x05, 0xc5, 0x89, 0x48, 0x26, 0xfc, 0x15,
0xda, 0x4a, 0x38, 0xe5, 0x69, 0x22, 0x55, 0x5e, 0xec, 0xf8, 0x45, 0x9c, 0xb2, 0xce, 0xd9, 0x55,
0xac, 0x5b, 0xf9, 0x99, 0x28, 0x3e, 0xf3, 0x5f, 0x0d, 0xed, 0x2d, 0xb7, 0x80, 0xdf, 0x45, 0x75,
0x9a, 0x7a, 0xbe, 0x30, 0xcd, 0xa5, 0xc4, 0x3b, 0xd9, 0xd4, 0xa8, 0x1f, 0x5e, 0x06, 0x49, 0x91,
0xc7, 0x0c, 0xed, 0x0e, 0x16, 0xdc, 0xa6, 0x7a, 0xec, 0xae, 0xef, 0xf1, 0x2a, 0x87, 0x3a, 0x38,
0x9b, 0x1a, 0xbb, 0x8b, 0x19, 0xb2, 0xc4, 0x8e, 0x3f, 0x46, 0xfb, 0xf0, 0x24, 0xf2, 0x63, 0xc9,
0xf4, 0x08, 0xdc, 0x90, 0x79, 0x89, 0xf4, 0x56, 0xc5, 0xb9, 0x95, 0x4d, 0x8d, 0xfd, 0xde, 0x72,
0x92, 0xac, 0xe2, 0xcd, 0xdf, 0x34, 0x84, 0x57, 0x55, 0xc2, 0x6f, 0xa1, 0x1a, 0x17, 0x51, 0xf5,
0x17, 0xd9, 0x51, 0xa2, 0xd5, 0x72, 0x68, 0x9e, 0xc3, 0x13, 0x74, 0xb3, 0x20, 0x7c, 0xec, 0x07,
0x90, 0x70, 0x1a, 0x44, 0xea, 0xb5, 0xdf, 0xd9, 0xcc, 0x4b, 0xa2, 0xcc, 0x79, 0x4d, 0xd1, 0xdf,
0xec, 0xad, 0xd2, 0x91, 0xab, 0xee, 0x30, 0x7f, 0x2e, 0xa3, 0x86, 0x6a, 0x7b, 0xec, 0xc3, 0x0f,
0x2f, 0xc1, 0xcb, 0x0f, 0x16, 0xbc, 0x7c, 0x7b, 0x23, 0xdf, 0x89, 0xd6, 0xae, 0xb5, 0xf2, 0x97,
0x4b, 0x56, 0xb6, 0x37, 0xa7, 0x5c, 0xef, 0xe4, 0xbb, 0xe8, 0x95, 0xa5, 0xfb, 0x37, 0x7a, 0x4e,
0xf3, 0x0f, 0x0d, 0xed, 0xaf, 0xdc, 0x82, 0x3f, 0x44, 0x3b, 0x73, 0xcd, 0x40, 0xbe, 0x34, 0xb7,
0x9d, 0x5b, 0x8a, 0x62, 0xe7, 0x70, 0x3e, 0x49, 0x16, 0xb1, 0xf8, 0x53, 0x54, 0x4d, 0x13, 0x88,
0x95, 0x68, 0x6f, 0xaf, 0x9f, 0xf0, 0x38, 0x81, 0xb8, 0xcf, 0x4e, 0xc3, 0x42, 0x2d, 0x11, 0x21,
0x92, 0x41, 0x4c, 0x00, 0x71, 0x1c, 0xc6, 0x6a, 0xbb, 0xce, 0x26, 0xe8, 0x89, 0x20, 0xc9, 0x73,
0xe6, 0xef, 0x65, 0xb4, 0x7d, 0xc9, 0x82, 0xdf, 0x43, 0xdb, 0xa2, 0x52, 0xae, 0xe4, 0x7c, 0xec,
0x3d, 0x55, 0x24, 0x31, 0x22, 0x4e, 0x66, 0x08, 0xfc, 0x06, 0xaa, 0xa4, 0xbe, 0xa7, 0x36, 0x7d,
0x63, 0x6e, 0x35, 0x13, 0x11, 0xc7, 0x26, 0xda, 0x1a, 0xc6, 0x61, 0x1a, 0x89, 0xc7, 0x12, 0x5b,
0x00, 0x09, 0xdd, 0x3f, 0x91, 0x11, 0xa2, 0x32, 0xf8, 0x04, 0xd5, 0x40, 0x6c, 0xe6, 0x66, 0xb5,
0x55, 0x69, 0x37, 0xba, 0x9d, 0xcd, 0xa6, 0xb5, 0xe4, 0x36, 0xef, 0x31, 0x1e, 0x4f, 0xe6, 0xa6,
0x12, 0x31, 0x92, 0xd3, 0x1d, 0x0c, 0xd4, 0xc6, 0x97, 0x18, 0xbc, 0x87, 0x2a, 0x23, 0x98, 0xe4,
0x13, 0x11, 0xf1, 0x13, 0x7f, 0x84, 0x6a, 0x63, 0xf1, 0x31, 0x50, 0x2a, 0xb7, 0xd7, 0xdf, 0x5b,
0x7c, 0x3c, 0x48, 0x5e, 0x76, 0xbf, 0x7c, 0x4f, 0x73, 0xda, 0xe7, 0x17, 0x7a, 0xe9, 0xd9, 0x85,
0x5e, 0x7a, 0x7e, 0xa1, 0x97, 0x9e, 0x66, 0xba, 0x76, 0x9e, 0xe9, 0xda, 0xb3, 0x4c, 0xd7, 0x9e,
0x67, 0xba, 0xf6, 0x77, 0xa6, 0x6b, 0x3f, 0xfe, 0xa3, 0x97, 0xbe, 0x2e, 0x8f, 0x3b, 0xff, 0x07,
0x00, 0x00, 0xff, 0xff, 0x5e, 0x8d, 0x94, 0x78, 0x88, 0x08, 0x00, 0x00,
// 900 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcf, 0x6f, 0xe3, 0x44,
0x14, 0x8e, 0xf3, 0xa3, 0x4a, 0x26, 0xdb, 0xd2, 0xce, 0xb2, 0x52, 0x54, 0xc0, 0x2e, 0x41, 0x42,
0x15, 0xb0, 0xf6, 0x26, 0x42, 0xb0, 0x5a, 0x24, 0xa4, 0x9a, 0x46, 0x10, 0x21, 0xd8, 0xd5, 0xec,
0xb6, 0x20, 0x4e, 0x4c, 0xec, 0xd7, 0xc4, 0x04, 0x8f, 0x8d, 0x3d, 0x0e, 0x9b, 0xdb, 0xfe, 0x09,
0x1c, 0x41, 0xe2, 0xc0, 0x1f, 0x81, 0xc4, 0xbf, 0xd0, 0xe3, 0x8a, 0xd3, 0x1e, 0x50, 0x44, 0xcd,
0x95, 0x23, 0x27, 0x4e, 0x68, 0xc6, 0xd3, 0x38, 0x4e, 0xda, 0x34, 0x27, 0x6e, 0x9e, 0xf7, 0xbe,
0xf7, 0xbd, 0x37, 0xdf, 0x7c, 0x9e, 0x41, 0xbd, 0xf1, 0xfd, 0xd8, 0xf4, 0x02, 0x6b, 0x9c, 0x0c,
0x20, 0x62, 0xc0, 0x21, 0xb6, 0x26, 0xc0, 0xdc, 0x20, 0xb2, 0x54, 0x82, 0x86, 0x9e, 0x45, 0x13,
0x3e, 0x02, 0xc6, 0x3d, 0x87, 0x72, 0x2f, 0x60, 0xd6, 0xa4, 0x63, 0x0d, 0x81, 0x41, 0x44, 0x39,
0xb8, 0x66, 0x18, 0x05, 0x3c, 0xc0, 0xaf, 0x66, 0x68, 0x93, 0x86, 0x9e, 0x59, 0x44, 0x9b, 0x93,
0xce, 0xfe, 0xdd, 0xa1, 0xc7, 0x47, 0xc9, 0xc0, 0x74, 0x02, 0xdf, 0x1a, 0x06, 0xc3, 0xc0, 0x92,
0x45, 0x83, 0xe4, 0x4c, 0xae, 0xe4, 0x42, 0x7e, 0x65, 0x64, 0xfb, 0xef, 0xe6, 0xad, 0x7d, 0xea,
0x8c, 0x3c, 0x06, 0xd1, 0xd4, 0x0a, 0xc7, 0x43, 0x11, 0x88, 0x2d, 0x1f, 0x38, 0xbd, 0x62, 0x84,
0x7d, 0xeb, 0xba, 0xaa, 0x28, 0x61, 0xdc, 0xf3, 0x61, 0xa5, 0xe0, 0xbd, 0x9b, 0x0a, 0x62, 0x67,
0x04, 0x3e, 0x5d, 0xae, 0x6b, 0xff, 0xae, 0xa1, 0x97, 0xed, 0x20, 0x61, 0xee, 0xc3, 0xc1, 0x37,
0xe0, 0x70, 0x02, 0x67, 0x10, 0x01, 0x73, 0x00, 0x1f, 0xa0, 0xea, 0xd8, 0x63, 0x6e, 0x4b, 0x3b,
0xd0, 0x0e, 0x1b, 0xf6, 0xad, 0xf3, 0x99, 0x51, 0x4a, 0x67, 0x46, 0xf5, 0x53, 0x8f, 0xb9, 0x44,
0x66, 0x70, 0x17, 0x21, 0xfa, 0xa8, 0x7f, 0x0a, 0x51, 0xec, 0x05, 0xac, 0x55, 0x96, 0x38, 0xac,
0x70, 0xe8, 0x68, 0x9e, 0x21, 0x0b, 0x28, 0xc1, 0xca, 0xa8, 0x0f, 0xad, 0x4a, 0x91, 0xf5, 0x73,
0xea, 0x03, 0x91, 0x19, 0x6c, 0xa3, 0x4a, 0xd2, 0x3f, 0x6e, 0x55, 0x25, 0xe0, 0x9e, 0x02, 0x54,
0x4e, 0xfa, 0xc7, 0xff, 0xce, 0x8c, 0xd7, 0xaf, 0xdb, 0x24, 0x9f, 0x86, 0x10, 0x9b, 0x27, 0xfd,
0x63, 0x22, 0x8a, 0xdb, 0xef, 0x23, 0xd4, 0x7b, 0xca, 0x23, 0x7a, 0x4a, 0xbf, 0x4d, 0x00, 0x1b,
0xa8, 0xe6, 0x71, 0xf0, 0xe3, 0x96, 0x76, 0x50, 0x39, 0x6c, 0xd8, 0x8d, 0x74, 0x66, 0xd4, 0xfa,
0x22, 0x40, 0xb2, 0xf8, 0x83, 0xfa, 0x8f, 0xbf, 0x18, 0xa5, 0x67, 0x7f, 0x1c, 0x94, 0xda, 0x3f,
0x97, 0xd1, 0xad, 0x27, 0xc1, 0x18, 0x18, 0x81, 0xef, 0x12, 0x88, 0x39, 0xfe, 0x1a, 0xd5, 0xc5,
0x11, 0xb9, 0x94, 0x53, 0xa9, 0x44, 0xb3, 0x7b, 0xcf, 0xcc, 0xdd, 0x31, 0x1f, 0xc2, 0x0c, 0xc7,
0x43, 0x11, 0x88, 0x4d, 0x81, 0x36, 0x27, 0x1d, 0x33, 0x93, 0xf3, 0x33, 0xe0, 0x34, 0xd7, 0x24,
0x8f, 0x91, 0x39, 0x2b, 0x7e, 0x84, 0xaa, 0x71, 0x08, 0x8e, 0xd4, 0xaf, 0xd9, 0x35, 0xcd, 0x75,
0xde, 0x33, 0x17, 0x67, 0x7b, 0x1c, 0x82, 0x93, 0x2b, 0x28, 0x56, 0x44, 0x32, 0xe1, 0x2f, 0xd1,
0x56, 0xcc, 0x29, 0x4f, 0x62, 0xa9, 0x72, 0x71, 0xe2, 0x9b, 0x38, 0x65, 0x9d, 0xbd, 0xa3, 0x58,
0xb7, 0xb2, 0x35, 0x51, 0x7c, 0xed, 0x7f, 0x34, 0xb4, 0xbb, 0x3c, 0x02, 0x7e, 0x1b, 0x35, 0x68,
0xe2, 0x7a, 0xc2, 0x34, 0x97, 0x12, 0x6f, 0xa7, 0x33, 0xa3, 0x71, 0x74, 0x19, 0x24, 0x79, 0x1e,
0x33, 0xb4, 0x33, 0x28, 0xb8, 0x4d, 0xcd, 0xd8, 0x5d, 0x3f, 0xe3, 0x55, 0x0e, 0xb5, 0x71, 0x3a,
0x33, 0x76, 0x8a, 0x19, 0xb2, 0xc4, 0x8e, 0x3f, 0x42, 0x7b, 0xf0, 0x34, 0xf4, 0x22, 0xc9, 0xf4,
0x18, 0x9c, 0x80, 0xb9, 0xb1, 0xf4, 0x56, 0xc5, 0xbe, 0x93, 0xce, 0x8c, 0xbd, 0xde, 0x72, 0x92,
0xac, 0xe2, 0xdb, 0xbf, 0x6a, 0x08, 0xaf, 0xaa, 0x84, 0xdf, 0x40, 0x35, 0x2e, 0xa2, 0xea, 0x17,
0xd9, 0x56, 0xa2, 0xd5, 0x32, 0x68, 0x96, 0xc3, 0x53, 0x74, 0x3b, 0x27, 0x7c, 0xe2, 0xf9, 0x10,
0x73, 0xea, 0x87, 0xea, 0xb4, 0xdf, 0xda, 0xcc, 0x4b, 0xa2, 0xcc, 0x7e, 0x45, 0xd1, 0xdf, 0xee,
0xad, 0xd2, 0x91, 0xab, 0x7a, 0xb4, 0x7f, 0x2a, 0xa3, 0xa6, 0x1a, 0x7b, 0xe2, 0xc1, 0xf7, 0xff,
0x83, 0x97, 0x1f, 0x16, 0xbc, 0x7c, 0x77, 0x23, 0xdf, 0x89, 0xd1, 0xae, 0xb5, 0xf2, 0x17, 0x4b,
0x56, 0xb6, 0x36, 0xa7, 0x5c, 0xef, 0x64, 0x07, 0xbd, 0xb4, 0xd4, 0x7f, 0xb3, 0xe3, 0x2c, 0x98,
0xbd, 0xbc, 0xde, 0xec, 0xed, 0xbf, 0x35, 0xb4, 0xb7, 0x32, 0x12, 0xfe, 0x00, 0x6d, 0x2f, 0x4c,
0x0e, 0xd9, 0x0d, 0x5b, 0xb7, 0xef, 0xa8, 0x7e, 0xdb, 0x47, 0x8b, 0x49, 0x52, 0xc4, 0xe2, 0x4f,
0x50, 0x35, 0x89, 0x21, 0x52, 0x0a, 0xbf, 0xb9, 0x5e, 0x8e, 0x93, 0x18, 0xa2, 0x3e, 0x3b, 0x0b,
0x72, 0x69, 0x45, 0x84, 0x48, 0x06, 0xb1, 0x5d, 0x88, 0xa2, 0x20, 0x52, 0x57, 0xf1, 0x7c, 0xbb,
0x3d, 0x11, 0x24, 0x59, 0xae, 0xb8, 0xdd, 0xea, 0x0d, 0xdb, 0xfd, 0xad, 0x8c, 0xea, 0x97, 0x2d,
0xf1, 0x3b, 0xa8, 0x2e, 0xda, 0xc8, 0xcb, 0x3e, 0x13, 0x74, 0x57, 0x75, 0x90, 0x18, 0x11, 0x27,
0x73, 0x04, 0x7e, 0x0d, 0x55, 0x12, 0xcf, 0x55, 0x6f, 0x48, 0x73, 0xe1, 0xd2, 0x27, 0x22, 0x8e,
0xdb, 0x68, 0x6b, 0x18, 0x05, 0x49, 0x28, 0x6c, 0x20, 0x66, 0x40, 0xe2, 0x44, 0x3f, 0x96, 0x11,
0xa2, 0x32, 0xf8, 0x14, 0xd5, 0x40, 0xdc, 0xf9, 0x72, 0xcc, 0x66, 0xb7, 0xb3, 0x99, 0x34, 0xa6,
0x7c, 0x27, 0x7a, 0x8c, 0x47, 0xd3, 0x05, 0x09, 0x44, 0x8c, 0x64, 0x74, 0xfb, 0x03, 0xf5, 0x96,
0x48, 0x0c, 0xde, 0x45, 0x95, 0x31, 0x4c, 0xb3, 0x1d, 0x11, 0xf1, 0x89, 0x3f, 0x44, 0xb5, 0x89,
0x78, 0x66, 0xd4, 0x91, 0x1c, 0xae, 0xef, 0x9b, 0x3f, 0x4b, 0x24, 0x2b, 0x7b, 0x50, 0xbe, 0xaf,
0xd9, 0x87, 0xe7, 0x17, 0x7a, 0xe9, 0xf9, 0x85, 0x5e, 0x7a, 0x71, 0xa1, 0x97, 0x9e, 0xa5, 0xba,
0x76, 0x9e, 0xea, 0xda, 0xf3, 0x54, 0xd7, 0x5e, 0xa4, 0xba, 0xf6, 0x67, 0xaa, 0x6b, 0x3f, 0xfc,
0xa5, 0x97, 0xbe, 0x2a, 0x4f, 0x3a, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x04, 0x81, 0x6f,
0xe2, 0x08, 0x00, 0x00,
}

View File

@ -118,6 +118,14 @@ message TokenReviewSpec {
// Token is the opaque bearer token.
// +optional
optional string token = 1;
// Audiences is a list of the identifiers that the resource server presented
// with the token identifies as. Audience-aware token authenticators will
// verify that the token was intended for at least one of the audiences in
// this list. If no audiences are provided, the audience will default to the
// audience of the Kubernetes apiserver.
// +optional
repeated string audiences = 2;
}
// TokenReviewStatus is the result of the token authentication request.
@ -130,6 +138,18 @@ message TokenReviewStatus {
// +optional
optional UserInfo user = 2;
// Audiences are audience identifiers chosen by the authenticator that are
// compatible with both the TokenReview and token. An identifier is any
// identifier in the intersection of the TokenReviewSpec audiences and the
// token's audiences. A client of the TokenReview API that sets the
// spec.audiences field should validate that a compatible audience identifier
// is returned in the status.audiences field to ensure that the TokenReview
// server is audience aware. If a TokenReview returns an empty
// status.audience field where status.authenticated is "true", the token is
// valid against the audience of the Kubernetes API server.
// +optional
repeated string audiences = 4;
// Error indicates that the token couldn't be checked
// +optional
optional string error = 3;

View File

@ -64,6 +64,13 @@ type TokenReviewSpec struct {
// Token is the opaque bearer token.
// +optional
Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"`
// Audiences is a list of the identifiers that the resource server presented
// with the token identifies as. Audience-aware token authenticators will
// verify that the token was intended for at least one of the audiences in
// this list. If no audiences are provided, the audience will default to the
// audience of the Kubernetes apiserver.
// +optional
Audiences []string `json:"audiences,omitempty" protobuf:"bytes,2,rep,name=audiences"`
}
// TokenReviewStatus is the result of the token authentication request.
@ -74,6 +81,17 @@ type TokenReviewStatus struct {
// User is the UserInfo associated with the provided token.
// +optional
User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"`
// Audiences are audience identifiers chosen by the authenticator that are
// compatible with both the TokenReview and token. An identifier is any
// identifier in the intersection of the TokenReviewSpec audiences and the
// token's audiences. A client of the TokenReview API that sets the
// spec.audiences field should validate that a compatible audience identifier
// is returned in the status.audiences field to ensure that the TokenReview
// server is audience aware. If a TokenReview returns an empty
// status.audience field where status.authenticated is "true", the token is
// valid against the audience of the Kubernetes API server.
// +optional
Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"`
// Error indicates that the token couldn't be checked
// +optional
Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"`

View File

@ -79,8 +79,9 @@ func (TokenReview) SwaggerDoc() map[string]string {
}
var map_TokenReviewSpec = map[string]string{
"": "TokenReviewSpec is a description of the token authentication request.",
"token": "Token is the opaque bearer token.",
"": "TokenReviewSpec is a description of the token authentication request.",
"token": "Token is the opaque bearer token.",
"audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
}
func (TokenReviewSpec) SwaggerDoc() map[string]string {
@ -91,6 +92,7 @@ var map_TokenReviewStatus = map[string]string{
"": "TokenReviewStatus is the result of the token authentication request.",
"authenticated": "Authenticated indicates that the token was associated with a known user.",
"user": "User is the UserInfo associated with the provided token.",
"audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"error": "Error indicates that the token couldn't be checked",
}

View File

@ -141,7 +141,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -167,6 +167,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
@ -184,6 +189,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}

View File

@ -175,6 +175,21 @@ func (m *TokenReviewSpec) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Token)))
i += copy(dAtA[i:], m.Token)
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
dAtA[i] = 0x12
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@ -213,6 +228,21 @@ func (m *TokenReviewStatus) MarshalTo(dAtA []byte) (int, error) {
i++
i = encodeVarintGenerated(dAtA, i, uint64(len(m.Error)))
i += copy(dAtA[i:], m.Error)
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
dAtA[i] = 0x22
i++
l = len(s)
for l >= 1<<7 {
dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
l >>= 7
i++
}
dAtA[i] = uint8(l)
i++
i += copy(dAtA[i:], s)
}
}
return i, nil
}
@ -326,6 +356,12 @@ func (m *TokenReviewSpec) Size() (n int) {
_ = l
l = len(m.Token)
n += 1 + l + sovGenerated(uint64(l))
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
@ -337,6 +373,12 @@ func (m *TokenReviewStatus) Size() (n int) {
n += 1 + l + sovGenerated(uint64(l))
l = len(m.Error)
n += 1 + l + sovGenerated(uint64(l))
if len(m.Audiences) > 0 {
for _, s := range m.Audiences {
l = len(s)
n += 1 + l + sovGenerated(uint64(l))
}
}
return n
}
@ -396,6 +438,7 @@ func (this *TokenReviewSpec) String() string {
}
s := strings.Join([]string{`&TokenReviewSpec{`,
`Token:` + fmt.Sprintf("%v", this.Token) + `,`,
`Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@ -408,6 +451,7 @@ func (this *TokenReviewStatus) String() string {
`Authenticated:` + fmt.Sprintf("%v", this.Authenticated) + `,`,
`User:` + strings.Replace(strings.Replace(this.User.String(), "UserInfo", "UserInfo", 1), `&`, ``, 1) + `,`,
`Error:` + fmt.Sprintf("%v", this.Error) + `,`,
`Audiences:` + fmt.Sprintf("%v", this.Audiences) + `,`,
`}`,
}, "")
return s
@ -720,6 +764,35 @@ func (m *TokenReviewSpec) Unmarshal(dAtA []byte) error {
}
m.Token = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -849,6 +922,35 @@ func (m *TokenReviewStatus) Unmarshal(dAtA []byte) error {
}
m.Error = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Audiences", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenerated
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Audiences = append(m.Audiences, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenerated(dAtA[iNdEx:])
@ -1240,45 +1342,47 @@ func init() {
}
var fileDescriptorGenerated = []byte{
// 635 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcf, 0x4f, 0xd4, 0x40,
0x14, 0x6e, 0xf7, 0x07, 0xee, 0xce, 0x8a, 0xe2, 0x24, 0x26, 0x9b, 0x4d, 0xec, 0xae, 0xeb, 0x85,
0x44, 0x99, 0x0a, 0x21, 0x48, 0xf0, 0x64, 0x95, 0x18, 0x4c, 0x88, 0xc9, 0x08, 0x1e, 0xd4, 0x83,
0xb3, 0xdd, 0x47, 0xb7, 0xae, 0xed, 0x34, 0xd3, 0x69, 0x95, 0x1b, 0x7f, 0x82, 0x47, 0x8f, 0x26,
0xfe, 0x25, 0x26, 0x1e, 0x38, 0x72, 0xe4, 0x60, 0x88, 0xd4, 0x7f, 0xc4, 0xcc, 0x74, 0x64, 0x17,
0x88, 0x01, 0x6e, 0xf3, 0xbe, 0xf7, 0xbe, 0x6f, 0xde, 0xf7, 0x66, 0x1e, 0x7a, 0x31, 0x5e, 0x4d,
0x49, 0xc8, 0xdd, 0x71, 0x36, 0x00, 0x11, 0x83, 0x84, 0xd4, 0xcd, 0x21, 0x1e, 0x72, 0xe1, 0x9a,
0x04, 0x4b, 0x42, 0x97, 0x65, 0x72, 0x04, 0xb1, 0x0c, 0x7d, 0x26, 0x43, 0x1e, 0xbb, 0xf9, 0xe2,
0x00, 0x24, 0x5b, 0x74, 0x03, 0x88, 0x41, 0x30, 0x09, 0x43, 0x92, 0x08, 0x2e, 0x39, 0xbe, 0x5b,
0x52, 0x08, 0x4b, 0x42, 0x72, 0x9a, 0x42, 0x0c, 0xa5, 0xb3, 0x10, 0x84, 0x72, 0x94, 0x0d, 0x88,
0xcf, 0x23, 0x37, 0xe0, 0x01, 0x77, 0x35, 0x73, 0x90, 0xed, 0xe8, 0x48, 0x07, 0xfa, 0x54, 0x2a,
0x76, 0x96, 0x27, 0x4d, 0x44, 0xcc, 0x1f, 0x85, 0x31, 0x88, 0x5d, 0x37, 0x19, 0x07, 0x0a, 0x48,
0xdd, 0x08, 0x24, 0x73, 0xf3, 0x73, 0x7d, 0x74, 0xdc, 0xff, 0xb1, 0x44, 0x16, 0xcb, 0x30, 0x82,
0x73, 0x84, 0x95, 0x8b, 0x08, 0xa9, 0x3f, 0x82, 0x88, 0x9d, 0xe5, 0xf5, 0x1f, 0x21, 0xb4, 0xfe,
0x59, 0x0a, 0xf6, 0x9a, 0x7d, 0xcc, 0x00, 0x77, 0x51, 0x3d, 0x94, 0x10, 0xa5, 0x6d, 0xbb, 0x57,
0x9d, 0x6f, 0x7a, 0xcd, 0xe2, 0xa8, 0x5b, 0xdf, 0x50, 0x00, 0x2d, 0xf1, 0xb5, 0xc6, 0xd7, 0x6f,
0x5d, 0x6b, 0xef, 0x57, 0xcf, 0xea, 0x7f, 0xaf, 0xa0, 0xd6, 0x16, 0x1f, 0x43, 0x4c, 0x21, 0x0f,
0xe1, 0x13, 0x7e, 0x8f, 0x1a, 0xca, 0xcc, 0x90, 0x49, 0xd6, 0xb6, 0x7b, 0xf6, 0x7c, 0x6b, 0xe9,
0x21, 0x99, 0x0c, 0xf3, 0xa4, 0x27, 0x92, 0x8c, 0x03, 0x05, 0xa4, 0x44, 0x55, 0x93, 0x7c, 0x91,
0xbc, 0x1c, 0x7c, 0x00, 0x5f, 0x6e, 0x82, 0x64, 0x1e, 0xde, 0x3f, 0xea, 0x5a, 0xc5, 0x51, 0x17,
0x4d, 0x30, 0x7a, 0xa2, 0x8a, 0xb7, 0x50, 0x2d, 0x4d, 0xc0, 0x6f, 0x57, 0xb4, 0xfa, 0x12, 0xb9,
0xf0, 0xa9, 0xc8, 0x54, 0x7f, 0xaf, 0x12, 0xf0, 0xbd, 0xeb, 0x46, 0xbf, 0xa6, 0x22, 0xaa, 0xd5,
0xf0, 0x3b, 0x34, 0x93, 0x4a, 0x26, 0xb3, 0xb4, 0x5d, 0xd5, 0xba, 0xcb, 0x57, 0xd4, 0xd5, 0x5c,
0xef, 0x86, 0x51, 0x9e, 0x29, 0x63, 0x6a, 0x34, 0xfb, 0x2b, 0xe8, 0xe6, 0x99, 0x26, 0xf0, 0x3d,
0x54, 0x97, 0x0a, 0xd2, 0x53, 0x6a, 0x7a, 0xb3, 0x86, 0x59, 0x2f, 0xeb, 0xca, 0x5c, 0xff, 0xa7,
0x8d, 0x6e, 0x9d, 0xbb, 0x05, 0x3f, 0x46, 0xb3, 0x53, 0x1d, 0xc1, 0x50, 0x4b, 0x34, 0xbc, 0xdb,
0x46, 0x62, 0xf6, 0xc9, 0x74, 0x92, 0x9e, 0xae, 0xc5, 0x9b, 0xa8, 0x96, 0xa5, 0x20, 0xcc, 0xf8,
0xee, 0x5f, 0xc2, 0xe6, 0x76, 0x0a, 0x62, 0x23, 0xde, 0xe1, 0x93, 0xb9, 0x29, 0x84, 0x6a, 0x19,
0x65, 0x03, 0x84, 0xe0, 0x42, 0x8f, 0x6d, 0xca, 0xc6, 0xba, 0x02, 0x69, 0x99, 0xeb, 0xff, 0xa8,
0xa0, 0xc6, 0x3f, 0x15, 0xfc, 0x00, 0x35, 0x14, 0x33, 0x66, 0x11, 0x18, 0xef, 0x73, 0x86, 0xa4,
0x6b, 0x14, 0x4e, 0x4f, 0x2a, 0xf0, 0x1d, 0x54, 0xcd, 0xc2, 0xa1, 0xee, 0xb6, 0xe9, 0xb5, 0x4c,
0x61, 0x75, 0x7b, 0xe3, 0x19, 0x55, 0x38, 0xee, 0xa3, 0x99, 0x40, 0xf0, 0x2c, 0x51, 0xcf, 0xa6,
0xbe, 0x2a, 0x52, 0xc3, 0x7f, 0xae, 0x11, 0x6a, 0x32, 0xf8, 0x2d, 0xaa, 0x83, 0xfa, 0xdb, 0xed,
0x5a, 0xaf, 0x3a, 0xdf, 0x5a, 0x5a, 0xb9, 0x82, 0x65, 0xa2, 0x97, 0x62, 0x3d, 0x96, 0x62, 0x77,
0xca, 0x9a, 0xc2, 0x68, 0xa9, 0xd9, 0x09, 0xcc, 0xe2, 0xe8, 0x1a, 0x3c, 0x87, 0xaa, 0x63, 0xd8,
0x2d, 0x6d, 0x51, 0x75, 0xc4, 0x4f, 0x51, 0x3d, 0x57, 0x3b, 0x65, 0xe6, 0xbd, 0x70, 0x89, 0xcb,
0x27, 0x8b, 0x48, 0x4b, 0xee, 0x5a, 0x65, 0xd5, 0xf6, 0x16, 0xf6, 0x8f, 0x1d, 0xeb, 0xe0, 0xd8,
0xb1, 0x0e, 0x8f, 0x1d, 0x6b, 0xaf, 0x70, 0xec, 0xfd, 0xc2, 0xb1, 0x0f, 0x0a, 0xc7, 0x3e, 0x2c,
0x1c, 0xfb, 0x77, 0xe1, 0xd8, 0x5f, 0xfe, 0x38, 0xd6, 0x9b, 0x6b, 0x46, 0xe4, 0x6f, 0x00, 0x00,
0x00, 0xff, 0xff, 0x39, 0x00, 0xe7, 0xfa, 0x0e, 0x05, 0x00, 0x00,
// 663 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xcd, 0x4e, 0x14, 0x4d,
0x14, 0xed, 0x9e, 0x1f, 0xbe, 0x99, 0x9a, 0x6f, 0x14, 0x2b, 0x31, 0x99, 0x4c, 0x62, 0x0f, 0x8e,
0x1b, 0x12, 0xa4, 0x5a, 0x08, 0x41, 0x82, 0x2b, 0x5a, 0x89, 0xc1, 0x84, 0x98, 0x94, 0xe0, 0x42,
0x5d, 0x58, 0xd3, 0x73, 0xe9, 0x69, 0xc7, 0xfe, 0x49, 0x55, 0xf5, 0x28, 0x3b, 0x1e, 0xc1, 0xa5,
0x4b, 0x13, 0x9f, 0xc4, 0x1d, 0x4b, 0x96, 0x2c, 0xcc, 0x44, 0xda, 0x27, 0xf0, 0x0d, 0x4c, 0x55,
0x17, 0xcc, 0x00, 0x31, 0xc0, 0xae, 0xeb, 0xdc, 0x7b, 0xce, 0x3d, 0xf7, 0x54, 0x17, 0x7a, 0x31,
0x5c, 0x13, 0x24, 0x4c, 0xdc, 0x61, 0xd6, 0x03, 0x1e, 0x83, 0x04, 0xe1, 0x8e, 0x20, 0xee, 0x27,
0xdc, 0x35, 0x05, 0x96, 0x86, 0x2e, 0xcb, 0xe4, 0x00, 0x62, 0x19, 0xfa, 0x4c, 0x86, 0x49, 0xec,
0x8e, 0x96, 0x7a, 0x20, 0xd9, 0x92, 0x1b, 0x40, 0x0c, 0x9c, 0x49, 0xe8, 0x93, 0x94, 0x27, 0x32,
0xc1, 0xf7, 0x0b, 0x0a, 0x61, 0x69, 0x48, 0xce, 0x53, 0x88, 0xa1, 0xb4, 0x17, 0x83, 0x50, 0x0e,
0xb2, 0x1e, 0xf1, 0x93, 0xc8, 0x0d, 0x92, 0x20, 0x71, 0x35, 0xb3, 0x97, 0xed, 0xe9, 0x93, 0x3e,
0xe8, 0xaf, 0x42, 0xb1, 0xbd, 0x32, 0x31, 0x11, 0x31, 0x7f, 0x10, 0xc6, 0xc0, 0xf7, 0xdd, 0x74,
0x18, 0x28, 0x40, 0xb8, 0x11, 0x48, 0xe6, 0x8e, 0x2e, 0xf9, 0x68, 0xbb, 0xff, 0x62, 0xf1, 0x2c,
0x96, 0x61, 0x04, 0x97, 0x08, 0xab, 0x57, 0x11, 0x84, 0x3f, 0x80, 0x88, 0x5d, 0xe4, 0x75, 0x1f,
0x23, 0xb4, 0xf9, 0x59, 0x72, 0xf6, 0x9a, 0x7d, 0xcc, 0x00, 0x77, 0x50, 0x35, 0x94, 0x10, 0x89,
0x96, 0x3d, 0x57, 0x9e, 0xaf, 0x7b, 0xf5, 0x7c, 0xdc, 0xa9, 0x6e, 0x29, 0x80, 0x16, 0xf8, 0x7a,
0xed, 0xeb, 0xb7, 0x8e, 0x75, 0xf0, 0x73, 0xce, 0xea, 0x7e, 0x2f, 0xa1, 0xc6, 0x4e, 0x32, 0x84,
0x98, 0xc2, 0x28, 0x84, 0x4f, 0xf8, 0x3d, 0xaa, 0xa9, 0x65, 0xfa, 0x4c, 0xb2, 0x96, 0x3d, 0x67,
0xcf, 0x37, 0x96, 0x1f, 0x91, 0x49, 0x98, 0x67, 0x9e, 0x48, 0x3a, 0x0c, 0x14, 0x20, 0x88, 0xea,
0x26, 0xa3, 0x25, 0xf2, 0xb2, 0xf7, 0x01, 0x7c, 0xb9, 0x0d, 0x92, 0x79, 0xf8, 0x70, 0xdc, 0xb1,
0xf2, 0x71, 0x07, 0x4d, 0x30, 0x7a, 0xa6, 0x8a, 0x77, 0x50, 0x45, 0xa4, 0xe0, 0xb7, 0x4a, 0x5a,
0x7d, 0x99, 0x5c, 0x79, 0x55, 0x64, 0xca, 0xdf, 0xab, 0x14, 0x7c, 0xef, 0x7f, 0xa3, 0x5f, 0x51,
0x27, 0xaa, 0xd5, 0xf0, 0x3b, 0x34, 0x23, 0x24, 0x93, 0x99, 0x68, 0x95, 0xb5, 0xee, 0xca, 0x0d,
0x75, 0x35, 0xd7, 0xbb, 0x65, 0x94, 0x67, 0x8a, 0x33, 0x35, 0x9a, 0x5d, 0x1f, 0xdd, 0xbe, 0x60,
0x02, 0x3f, 0x40, 0x55, 0xa9, 0x20, 0x9d, 0x52, 0xdd, 0x6b, 0x1a, 0x66, 0xb5, 0xe8, 0x2b, 0x6a,
0x78, 0x01, 0xd5, 0x59, 0xd6, 0x0f, 0x21, 0xf6, 0x41, 0xb4, 0x4a, 0xfa, 0x32, 0x9a, 0xf9, 0xb8,
0x53, 0xdf, 0x38, 0x05, 0xe9, 0xa4, 0xde, 0xfd, 0x63, 0xa3, 0x3b, 0x97, 0x2c, 0xe1, 0x27, 0xa8,
0x39, 0x65, 0x1f, 0xfa, 0x7a, 0x5e, 0xcd, 0xbb, 0x6b, 0xe6, 0x35, 0x37, 0xa6, 0x8b, 0xf4, 0x7c,
0x2f, 0xde, 0x46, 0x95, 0x4c, 0x00, 0x37, 0x59, 0x2f, 0x5c, 0x23, 0x93, 0x5d, 0x01, 0x7c, 0x2b,
0xde, 0x4b, 0x26, 0x21, 0x2b, 0x84, 0x6a, 0x19, 0xb5, 0x33, 0x70, 0x9e, 0x70, 0x9d, 0xf1, 0xd4,
0xce, 0x9b, 0x0a, 0xa4, 0x45, 0xed, 0xfc, 0xce, 0x95, 0x2b, 0x76, 0xfe, 0x51, 0x42, 0xb5, 0xd3,
0x91, 0xf8, 0x21, 0xaa, 0xa9, 0x31, 0x31, 0x8b, 0xc0, 0xa4, 0x3a, 0x6b, 0x26, 0xe8, 0x1e, 0x85,
0xd3, 0xb3, 0x0e, 0x7c, 0x0f, 0x95, 0xb3, 0xb0, 0xaf, 0x57, 0xab, 0x7b, 0x0d, 0xd3, 0x58, 0xde,
0xdd, 0x7a, 0x46, 0x15, 0x8e, 0xbb, 0x68, 0x26, 0xe0, 0x49, 0x96, 0xaa, 0x1f, 0x42, 0x79, 0x40,
0xea, 0x5a, 0x9f, 0x6b, 0x84, 0x9a, 0x0a, 0x7e, 0x8b, 0xaa, 0xa0, 0x5e, 0x8d, 0xb6, 0xd9, 0x58,
0x5e, 0xbd, 0x41, 0x3e, 0x44, 0x3f, 0xb7, 0xcd, 0x58, 0xf2, 0xfd, 0xa9, 0x1c, 0x14, 0x46, 0x0b,
0xcd, 0x76, 0x60, 0x9e, 0xa4, 0xee, 0xc1, 0xb3, 0xa8, 0x3c, 0x84, 0xfd, 0x62, 0x2d, 0xaa, 0x3e,
0xf1, 0x53, 0x54, 0x1d, 0xa9, 0xd7, 0x6a, 0x2e, 0x67, 0xf1, 0x1a, 0xc3, 0x27, 0x4f, 0x9c, 0x16,
0xdc, 0xf5, 0xd2, 0x9a, 0xed, 0x2d, 0x1e, 0x9e, 0x38, 0xd6, 0xd1, 0x89, 0x63, 0x1d, 0x9f, 0x38,
0xd6, 0x41, 0xee, 0xd8, 0x87, 0xb9, 0x63, 0x1f, 0xe5, 0x8e, 0x7d, 0x9c, 0x3b, 0xf6, 0xaf, 0xdc,
0xb1, 0xbf, 0xfc, 0x76, 0xac, 0x37, 0xff, 0x19, 0x91, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf7,
0xd6, 0x32, 0x28, 0x68, 0x05, 0x00, 0x00,
}

View File

@ -57,6 +57,14 @@ message TokenReviewSpec {
// Token is the opaque bearer token.
// +optional
optional string token = 1;
// Audiences is a list of the identifiers that the resource server presented
// with the token identifies as. Audience-aware token authenticators will
// verify that the token was intended for at least one of the audiences in
// this list. If no audiences are provided, the audience will default to the
// audience of the Kubernetes apiserver.
// +optional
repeated string audiences = 2;
}
// TokenReviewStatus is the result of the token authentication request.
@ -69,6 +77,18 @@ message TokenReviewStatus {
// +optional
optional UserInfo user = 2;
// Audiences are audience identifiers chosen by the authenticator that are
// compatible with both the TokenReview and token. An identifier is any
// identifier in the intersection of the TokenReviewSpec audiences and the
// token's audiences. A client of the TokenReview API that sets the
// spec.audiences field should validate that a compatible audience identifier
// is returned in the status.audiences field to ensure that the TokenReview
// server is audience aware. If a TokenReview returns an empty
// status.audience field where status.authenticated is "true", the token is
// valid against the audience of the Kubernetes API server.
// +optional
repeated string audiences = 4;
// Error indicates that the token couldn't be checked
// +optional
optional string error = 3;

View File

@ -48,6 +48,13 @@ type TokenReviewSpec struct {
// Token is the opaque bearer token.
// +optional
Token string `json:"token,omitempty" protobuf:"bytes,1,opt,name=token"`
// Audiences is a list of the identifiers that the resource server presented
// with the token identifies as. Audience-aware token authenticators will
// verify that the token was intended for at least one of the audiences in
// this list. If no audiences are provided, the audience will default to the
// audience of the Kubernetes apiserver.
// +optional
Audiences []string `json:"audiences,omitempty" protobuf:"bytes,2,rep,name=audiences"`
}
// TokenReviewStatus is the result of the token authentication request.
@ -58,6 +65,17 @@ type TokenReviewStatus struct {
// User is the UserInfo associated with the provided token.
// +optional
User UserInfo `json:"user,omitempty" protobuf:"bytes,2,opt,name=user"`
// Audiences are audience identifiers chosen by the authenticator that are
// compatible with both the TokenReview and token. An identifier is any
// identifier in the intersection of the TokenReviewSpec audiences and the
// token's audiences. A client of the TokenReview API that sets the
// spec.audiences field should validate that a compatible audience identifier
// is returned in the status.audiences field to ensure that the TokenReview
// server is audience aware. If a TokenReview returns an empty
// status.audience field where status.authenticated is "true", the token is
// valid against the audience of the Kubernetes API server.
// +optional
Audiences []string `json:"audiences,omitempty" protobuf:"bytes,4,rep,name=audiences"`
// Error indicates that the token couldn't be checked
// +optional
Error string `json:"error,omitempty" protobuf:"bytes,3,opt,name=error"`

View File

@ -38,8 +38,9 @@ func (TokenReview) SwaggerDoc() map[string]string {
}
var map_TokenReviewSpec = map[string]string{
"": "TokenReviewSpec is a description of the token authentication request.",
"token": "Token is the opaque bearer token.",
"": "TokenReviewSpec is a description of the token authentication request.",
"token": "Token is the opaque bearer token.",
"audiences": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
}
func (TokenReviewSpec) SwaggerDoc() map[string]string {
@ -50,6 +51,7 @@ var map_TokenReviewStatus = map[string]string{
"": "TokenReviewStatus is the result of the token authentication request.",
"authenticated": "Authenticated indicates that the token was associated with a known user.",
"user": "User is the UserInfo associated with the provided token.",
"audiences": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
"error": "Error indicates that the token couldn't be checked",
}

View File

@ -49,7 +49,7 @@ func (in *TokenReview) DeepCopyInto(out *TokenReview) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
return
}
@ -75,6 +75,11 @@ func (in *TokenReview) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TokenReviewSpec) DeepCopyInto(out *TokenReviewSpec) {
*out = *in
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
@ -92,6 +97,11 @@ func (in *TokenReviewSpec) DeepCopy() *TokenReviewSpec {
func (in *TokenReviewStatus) DeepCopyInto(out *TokenReviewStatus) {
*out = *in
in.User.DeepCopyInto(&out.User)
if in.Audiences != nil {
in, out := &in.Audiences, &out.Audiences
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}

View File

@ -51,6 +51,8 @@ type DelegatingAuthenticatorConfig struct {
// ClientCAFile is the CA bundle file used to authenticate client certificates
ClientCAFile string
APIAudiences authenticator.Audiences
RequestHeaderConfig *RequestHeaderConfig
}
@ -86,7 +88,7 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur
}
if c.TokenAccessReviewClient != nil {
tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient)
tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences)
if err != nil {
return nil, nil, err
}

View File

@ -21,8 +21,6 @@ import (
"context"
"time"
"k8s.io/klog"
authentication "k8s.io/api/authentication/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@ -31,6 +29,7 @@ import (
"k8s.io/apiserver/pkg/util/webhook"
"k8s.io/client-go/kubernetes/scheme"
authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1beta1"
"k8s.io/klog"
)
var (
@ -45,38 +44,58 @@ var _ authenticator.Token = (*WebhookTokenAuthenticator)(nil)
type WebhookTokenAuthenticator struct {
tokenReview authenticationclient.TokenReviewInterface
initialBackoff time.Duration
implicitAuds authenticator.Audiences
}
// NewFromInterface creates a webhook authenticator using the given tokenReview
// client. It is recommend to wrap this authenticator with the token cache
// authenticator implemented in
// k8s.io/apiserver/pkg/authentication/token/cache.
func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface) (*WebhookTokenAuthenticator, error) {
return newWithBackoff(tokenReview, retryBackoff)
func NewFromInterface(tokenReview authenticationclient.TokenReviewInterface, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
}
// New creates a new WebhookTokenAuthenticator from the provided kubeconfig file.
func New(kubeConfigFile string) (*WebhookTokenAuthenticator, error) {
// New creates a new WebhookTokenAuthenticator from the provided kubeconfig
// file. It is recommend to wrap this authenticator with the token cache
// authenticator implemented in
// k8s.io/apiserver/pkg/authentication/token/cache.
func New(kubeConfigFile string, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile)
if err != nil {
return nil, err
}
return newWithBackoff(tokenReview, retryBackoff)
return newWithBackoff(tokenReview, retryBackoff, implicitAuds)
}
// newWithBackoff allows tests to skip the sleep.
func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, initialBackoff time.Duration) (*WebhookTokenAuthenticator, error) {
return &WebhookTokenAuthenticator{tokenReview, initialBackoff}, nil
func newWithBackoff(tokenReview authenticationclient.TokenReviewInterface, initialBackoff time.Duration, implicitAuds authenticator.Audiences) (*WebhookTokenAuthenticator, error) {
return &WebhookTokenAuthenticator{tokenReview, initialBackoff, implicitAuds}, nil
}
// AuthenticateToken implements the authenticator.Token interface.
func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token string) (*authenticator.Response, bool, error) {
// We take implicit audiences of the API server at WebhookTokenAuthenticator
// construction time. The outline of how we validate audience here is:
//
// * if the ctx is not audience limited, don't do any audience validation.
// * if ctx is audience-limited, add the audiences to the tokenreview spec
// * if the tokenreview returns with audiences in the status that intersect
// with the audiences in the ctx, copy into the response and return success
// * if the tokenreview returns without an audience in the status, ensure
// the ctx audiences intersect with the implicit audiences, and set the
// intersection in the response.
// * otherwise return unauthenticated.
wantAuds, checkAuds := authenticator.AudiencesFrom(ctx)
r := &authentication.TokenReview{
Spec: authentication.TokenReviewSpec{Token: token},
Spec: authentication.TokenReviewSpec{
Token: token,
Audiences: wantAuds,
},
}
var (
result *authentication.TokenReview
err error
auds authenticator.Audiences
)
webhook.WithExponentialBackoff(w.initialBackoff, func() error {
result, err = w.tokenReview.Create(r)
@ -87,6 +106,18 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
klog.Errorf("Failed to make webhook authenticator request: %v", err)
return nil, false, err
}
if checkAuds {
gotAuds := w.implicitAuds
if len(result.Status.Audiences) > 0 {
gotAuds = result.Status.Audiences
}
auds = wantAuds.Intersect(gotAuds)
if len(auds) == 0 {
return nil, false, nil
}
}
r.Status = result.Status
if !r.Status.Authenticated {
return nil, false, nil
@ -107,6 +138,7 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
Groups: r.Status.User.Groups,
Extra: extra,
},
Audiences: auds,
}, true, nil
}

View File

@ -39,6 +39,8 @@ import (
"k8s.io/client-go/tools/clientcmd/api/v1"
)
var apiAuds = authenticator.Audiences{"api"}
// Service mocks a remote authentication service.
type Service interface {
// Review looks at the TokenReviewSpec and provides an authentication
@ -105,6 +107,7 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
type status struct {
Authenticated bool `json:"authenticated"`
User userInfo `json:"user"`
Audiences []string `json:"audiences"`
}
var extra map[string][]string
@ -130,6 +133,7 @@ func NewTestServer(s Service, cert, key, caCert []byte) (*httptest.Server, error
Groups: review.Status.User.Groups,
Extra: extra,
},
review.Status.Audiences,
},
}
w.Header().Set("Content-Type", "application/json")
@ -168,7 +172,7 @@ func (m *mockService) HTTPStatusCode() int { return m.statusCode }
// newTokenAuthenticator creates a temporary kubeconfig file from the provided
// arguments and attempts to load a new WebhookTokenAuthenticator from it.
func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration) (authenticator.Token, error) {
func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration, implicitAuds authenticator.Audiences) (authenticator.Token, error) {
tempfile, err := ioutil.TempFile("", "")
if err != nil {
return nil, err
@ -196,7 +200,7 @@ func newTokenAuthenticator(serverURL string, clientCert, clientKey, ca []byte, c
return nil, err
}
authn, err := newWithBackoff(c, 0)
authn, err := newWithBackoff(c, 0, implicitAuds)
if err != nil {
return nil, err
}
@ -257,7 +261,7 @@ func TestTLSConfig(t *testing.T) {
}
defer server.Close()
wh, err := newTokenAuthenticator(server.URL, tt.clientCert, tt.clientKey, tt.clientCA, 0)
wh, err := newTokenAuthenticator(server.URL, tt.clientCert, tt.clientKey, tt.clientCA, 0, nil)
if err != nil {
t.Errorf("%s: failed to create client: %v", tt.test, err)
return
@ -312,23 +316,21 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
}
defer s.Close()
wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 0)
if err != nil {
t.Fatal(err)
}
expTypeMeta := metav1.TypeMeta{
APIVersion: "authentication.k8s.io/v1beta1",
Kind: "TokenReview",
}
tests := []struct {
description string
implicitAuds, reqAuds authenticator.Audiences
serverResponse v1beta1.TokenReviewStatus
expectedAuthenticated bool
expectedUser *user.DefaultInfo
expectedAuds authenticator.Audiences
}{
// Successful response should pass through all user info.
{
description: "successful response should pass through all user info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
@ -341,6 +343,7 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
},
},
{
description: "successful response should pass through all user info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
@ -358,8 +361,8 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
Extra: map[string][]string{"foo": {"bar", "baz"}},
},
},
// Unauthenticated shouldn't even include extra provided info.
{
description: "unauthenticated shouldn't even include extra provided info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: false,
User: v1beta1.UserInfo{
@ -372,37 +375,151 @@ func TestWebhookTokenAuthenticator(t *testing.T) {
expectedUser: nil,
},
{
description: "unauthenticated shouldn't even include extra provided info.",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: false,
},
expectedAuthenticated: false,
expectedUser: nil,
},
{
description: "good audience",
implicitAuds: apiAuds,
reqAuds: apiAuds,
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
},
expectedAuthenticated: true,
expectedUser: &user.DefaultInfo{
Name: "somebody",
},
expectedAuds: apiAuds,
},
{
description: "good audience",
implicitAuds: append(apiAuds, "other"),
reqAuds: apiAuds,
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
},
expectedAuthenticated: true,
expectedUser: &user.DefaultInfo{
Name: "somebody",
},
expectedAuds: apiAuds,
},
{
description: "bad audiences",
implicitAuds: apiAuds,
reqAuds: authenticator.Audiences{"other"},
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: false,
},
expectedAuthenticated: false,
},
{
description: "bad audiences",
implicitAuds: apiAuds,
reqAuds: authenticator.Audiences{"other"},
// webhook authenticator hasn't been upgraded to support audience.
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
},
expectedAuthenticated: false,
},
{
description: "audience aware backend",
implicitAuds: apiAuds,
reqAuds: apiAuds,
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
Audiences: []string(apiAuds),
},
expectedAuthenticated: true,
expectedUser: &user.DefaultInfo{
Name: "somebody",
},
expectedAuds: apiAuds,
},
{
description: "audience aware backend",
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
Audiences: []string(apiAuds),
},
expectedAuthenticated: true,
expectedUser: &user.DefaultInfo{
Name: "somebody",
},
},
{
description: "audience aware backend",
implicitAuds: apiAuds,
reqAuds: apiAuds,
serverResponse: v1beta1.TokenReviewStatus{
Authenticated: true,
User: v1beta1.UserInfo{
Username: "somebody",
},
Audiences: []string{"other"},
},
expectedAuthenticated: false,
},
}
token := "my-s3cr3t-t0ken"
for i, tt := range tests {
serv.response = tt.serverResponse
resp, authenticated, err := wh.AuthenticateToken(context.Background(), token)
if err != nil {
t.Errorf("case %d: authentication failed: %v", i, err)
continue
}
if serv.lastRequest.Spec.Token != token {
t.Errorf("case %d: Server did not see correct token. Got %q, expected %q.",
i, serv.lastRequest.Spec.Token, token)
}
if !reflect.DeepEqual(serv.lastRequest.TypeMeta, expTypeMeta) {
t.Errorf("case %d: Server did not see correct TypeMeta. Got %v, expected %v",
i, serv.lastRequest.TypeMeta, expTypeMeta)
}
if authenticated != tt.expectedAuthenticated {
t.Errorf("case %d: Plugin returned incorrect authentication response. Got %t, expected %t.",
i, authenticated, tt.expectedAuthenticated)
}
if resp != nil && tt.expectedUser != nil && !reflect.DeepEqual(resp.User, tt.expectedUser) {
t.Errorf("case %d: Plugin returned incorrect user. Got %#v, expected %#v",
i, resp.User, tt.expectedUser)
}
for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) {
wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 0, tt.implicitAuds)
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
if tt.reqAuds != nil {
ctx = authenticator.WithAudiences(ctx, tt.reqAuds)
}
serv.response = tt.serverResponse
resp, authenticated, err := wh.AuthenticateToken(ctx, token)
if err != nil {
t.Fatalf("authentication failed: %v", err)
}
if serv.lastRequest.Spec.Token != token {
t.Errorf("Server did not see correct token. Got %q, expected %q.",
serv.lastRequest.Spec.Token, token)
}
if !reflect.DeepEqual(serv.lastRequest.TypeMeta, expTypeMeta) {
t.Errorf("Server did not see correct TypeMeta. Got %v, expected %v",
serv.lastRequest.TypeMeta, expTypeMeta)
}
if authenticated != tt.expectedAuthenticated {
t.Errorf("Plugin returned incorrect authentication response. Got %t, expected %t.",
authenticated, tt.expectedAuthenticated)
}
if resp != nil && tt.expectedUser != nil && !reflect.DeepEqual(resp.User, tt.expectedUser) {
t.Errorf("Plugin returned incorrect user. Got %#v, expected %#v",
resp.User, tt.expectedUser)
}
if resp != nil && tt.expectedAuds != nil && !reflect.DeepEqual(resp.Audiences, tt.expectedAuds) {
t.Errorf("Plugin returned incorrect audiences. Got %#v, expected %#v",
resp.Audiences, tt.expectedAuds)
}
})
}
}
@ -440,7 +557,7 @@ func TestWebhookCacheAndRetry(t *testing.T) {
defer s.Close()
// Create an authenticator that caches successful responses "forever" (100 days).
wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 2400*time.Hour)
wh, err := newTokenAuthenticator(s.URL, clientCert, clientKey, caCert, 2400*time.Hour, nil)
if err != nil {
t.Fatal(err)
}

View File

@ -85,7 +85,7 @@ func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) {
if err := json.NewEncoder(kubecfgFile).Encode(config); err != nil {
return nil, err
}
webhookTokenAuth, err := webhook.New(kubecfgFile.Name())
webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), nil)
if err != nil {
return nil, err
}