k8s.io/kubernetes@v1.29.3/pkg/registry/authentication/tokenreview/storage.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package tokenreview 18 19 import ( 20 "context" 21 "errors" 22 "fmt" 23 "net/http" 24 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/runtime" 28 "k8s.io/apiserver/pkg/authentication/authenticator" 29 genericapirequest "k8s.io/apiserver/pkg/endpoints/request" 30 "k8s.io/apiserver/pkg/registry/rest" 31 "k8s.io/klog/v2" 32 "k8s.io/kubernetes/pkg/apis/authentication" 33 ) 34 35 var badAuthenticatorAuds = apierrors.NewInternalError(errors.New("error validating audiences")) 36 37 type REST struct { 38 tokenAuthenticator authenticator.Request 39 apiAudiences []string 40 } 41 42 func NewREST(tokenAuthenticator authenticator.Request, apiAudiences []string) *REST { 43 return &REST{ 44 tokenAuthenticator: tokenAuthenticator, 45 apiAudiences: apiAudiences, 46 } 47 } 48 49 func (r *REST) NamespaceScoped() bool { 50 return false 51 } 52 53 func (r *REST) New() runtime.Object { 54 return &authentication.TokenReview{} 55 } 56 57 // Destroy cleans up resources on shutdown. 58 func (r *REST) Destroy() { 59 // Given no underlying store, we don't destroy anything 60 // here explicitly. 61 } 62 63 var _ rest.SingularNameProvider = &REST{} 64 65 func (r *REST) GetSingularName() string { 66 return "tokenreview" 67 } 68 69 func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { 70 tokenReview, ok := obj.(*authentication.TokenReview) 71 if !ok { 72 return nil, apierrors.NewBadRequest(fmt.Sprintf("not a TokenReview: %#v", obj)) 73 } 74 namespace := genericapirequest.NamespaceValue(ctx) 75 if len(namespace) != 0 { 76 return nil, apierrors.NewBadRequest(fmt.Sprintf("namespace is not allowed on this type: %v", namespace)) 77 } 78 79 if len(tokenReview.Spec.Token) == 0 { 80 return nil, apierrors.NewBadRequest(fmt.Sprintf("token is required for TokenReview in authentication")) 81 } 82 83 if createValidation != nil { 84 if err := createValidation(ctx, obj.DeepCopyObject()); err != nil { 85 return nil, err 86 } 87 } 88 89 if r.tokenAuthenticator == nil { 90 return tokenReview, nil 91 } 92 93 // create a header that contains nothing but the token 94 fakeReq := &http.Request{Header: http.Header{}} 95 fakeReq.Header.Add("Authorization", "Bearer "+tokenReview.Spec.Token) 96 97 auds := tokenReview.Spec.Audiences 98 if len(auds) == 0 { 99 auds = r.apiAudiences 100 } 101 if len(auds) > 0 { 102 fakeReq = fakeReq.WithContext(authenticator.WithAudiences(fakeReq.Context(), auds)) 103 } 104 105 resp, ok, err := r.tokenAuthenticator.AuthenticateRequest(fakeReq) 106 tokenReview.Status.Authenticated = ok 107 if err != nil { 108 tokenReview.Status.Error = err.Error() 109 } 110 111 if len(auds) > 0 && resp != nil && len(authenticator.Audiences(auds).Intersect(resp.Audiences)) == 0 { 112 klog.Errorf("error validating audience. want=%q got=%q", auds, resp.Audiences) 113 return nil, badAuthenticatorAuds 114 } 115 116 if resp != nil && resp.User != nil { 117 tokenReview.Status.User = authentication.UserInfo{ 118 Username: resp.User.GetName(), 119 UID: resp.User.GetUID(), 120 Groups: resp.User.GetGroups(), 121 Extra: map[string]authentication.ExtraValue{}, 122 } 123 for k, v := range resp.User.GetExtra() { 124 tokenReview.Status.User.Extra[k] = authentication.ExtraValue(v) 125 } 126 tokenReview.Status.Audiences = resp.Audiences 127 } 128 129 return tokenReview, nil 130 }