k8s.io/apiserver@v0.31.1/pkg/authentication/authenticatorfactory/delegating.go (about)

     1  /*
     2  Copyright 2016 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 authenticatorfactory
    18  
    19  import (
    20  	"errors"
    21  	"time"
    22  
    23  	"k8s.io/apimachinery/pkg/util/wait"
    24  	"k8s.io/apiserver/pkg/apis/apiserver"
    25  	"k8s.io/apiserver/pkg/authentication/authenticator"
    26  	"k8s.io/apiserver/pkg/authentication/group"
    27  	"k8s.io/apiserver/pkg/authentication/request/anonymous"
    28  	"k8s.io/apiserver/pkg/authentication/request/bearertoken"
    29  	"k8s.io/apiserver/pkg/authentication/request/headerrequest"
    30  	unionauth "k8s.io/apiserver/pkg/authentication/request/union"
    31  	"k8s.io/apiserver/pkg/authentication/request/websocket"
    32  	"k8s.io/apiserver/pkg/authentication/request/x509"
    33  	"k8s.io/apiserver/pkg/authentication/token/cache"
    34  	"k8s.io/apiserver/pkg/server/dynamiccertificates"
    35  	webhooktoken "k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
    36  	authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1"
    37  	"k8s.io/kube-openapi/pkg/validation/spec"
    38  )
    39  
    40  // DelegatingAuthenticatorConfig is the minimal configuration needed to create an authenticator
    41  // built to delegate authentication to a kube API server
    42  type DelegatingAuthenticatorConfig struct {
    43  	Anonymous *apiserver.AnonymousAuthConfig
    44  
    45  	// TokenAccessReviewClient is a client to do token review. It can be nil. Then every token is ignored.
    46  	TokenAccessReviewClient authenticationclient.AuthenticationV1Interface
    47  
    48  	// TokenAccessReviewTimeout specifies a time limit for requests made by the authorization webhook client.
    49  	TokenAccessReviewTimeout time.Duration
    50  
    51  	// WebhookRetryBackoff specifies the backoff parameters for the authentication webhook retry logic.
    52  	// This allows us to configure the sleep time at each iteration and the maximum number of retries allowed
    53  	// before we fail the webhook call in order to limit the fan out that ensues when the system is degraded.
    54  	WebhookRetryBackoff *wait.Backoff
    55  
    56  	// CacheTTL is the length of time that a token authentication answer will be cached.
    57  	CacheTTL time.Duration
    58  
    59  	// CAContentProvider are the options for verifying incoming connections using mTLS and directly assigning to users.
    60  	// Generally this is the CA bundle file used to authenticate client certificates
    61  	// If this is nil, then mTLS will not be used.
    62  	ClientCertificateCAContentProvider dynamiccertificates.CAContentProvider
    63  
    64  	APIAudiences authenticator.Audiences
    65  
    66  	RequestHeaderConfig *RequestHeaderConfig
    67  }
    68  
    69  func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) {
    70  	authenticators := []authenticator.Request{}
    71  	securityDefinitions := spec.SecurityDefinitions{}
    72  
    73  	// front-proxy first, then remote
    74  	// Add the front proxy authenticator if requested
    75  	if c.RequestHeaderConfig != nil {
    76  		requestHeaderAuthenticator := headerrequest.NewDynamicVerifyOptionsSecure(
    77  			c.RequestHeaderConfig.CAContentProvider.VerifyOptions,
    78  			c.RequestHeaderConfig.AllowedClientNames,
    79  			c.RequestHeaderConfig.UsernameHeaders,
    80  			c.RequestHeaderConfig.GroupHeaders,
    81  			c.RequestHeaderConfig.ExtraHeaderPrefixes,
    82  		)
    83  		authenticators = append(authenticators, requestHeaderAuthenticator)
    84  	}
    85  
    86  	// x509 client cert auth
    87  	if c.ClientCertificateCAContentProvider != nil {
    88  		authenticators = append(authenticators, x509.NewDynamic(c.ClientCertificateCAContentProvider.VerifyOptions, x509.CommonNameUserConversion))
    89  	}
    90  
    91  	if c.TokenAccessReviewClient != nil {
    92  		if c.WebhookRetryBackoff == nil {
    93  			return nil, nil, errors.New("retry backoff parameters for delegating authentication webhook has not been specified")
    94  		}
    95  		tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences, *c.WebhookRetryBackoff, c.TokenAccessReviewTimeout, webhooktoken.AuthenticatorMetrics{
    96  			RecordRequestTotal:   RecordRequestTotal,
    97  			RecordRequestLatency: RecordRequestLatency,
    98  		})
    99  		if err != nil {
   100  			return nil, nil, err
   101  		}
   102  		cachingTokenAuth := cache.New(tokenAuth, false, c.CacheTTL, c.CacheTTL)
   103  		authenticators = append(authenticators, bearertoken.New(cachingTokenAuth), websocket.NewProtocolAuthenticator(cachingTokenAuth))
   104  
   105  		securityDefinitions["BearerToken"] = &spec.SecurityScheme{
   106  			SecuritySchemeProps: spec.SecuritySchemeProps{
   107  				Type:        "apiKey",
   108  				Name:        "authorization",
   109  				In:          "header",
   110  				Description: "Bearer Token authentication",
   111  			},
   112  		}
   113  	}
   114  
   115  	if len(authenticators) == 0 {
   116  		if c.Anonymous != nil && c.Anonymous.Enabled {
   117  			return anonymous.NewAuthenticator(c.Anonymous.Conditions), &securityDefinitions, nil
   118  		}
   119  		return nil, nil, errors.New("no authentication method configured")
   120  	}
   121  
   122  	authenticator := group.NewAuthenticatedGroupAdder(unionauth.New(authenticators...))
   123  	if c.Anonymous != nil && c.Anonymous.Enabled {
   124  		authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator(c.Anonymous.Conditions))
   125  	}
   126  	return authenticator, &securityDefinitions, nil
   127  }