113 lines
4.1 KiB
Go
113 lines
4.1 KiB
Go
/*
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package authenticatorfactory
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/go-openapi/spec"
|
|
|
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
"k8s.io/apiserver/pkg/authentication/group"
|
|
"k8s.io/apiserver/pkg/authentication/request/anonymous"
|
|
"k8s.io/apiserver/pkg/authentication/request/bearertoken"
|
|
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
|
unionauth "k8s.io/apiserver/pkg/authentication/request/union"
|
|
"k8s.io/apiserver/pkg/authentication/request/websocket"
|
|
"k8s.io/apiserver/pkg/authentication/request/x509"
|
|
"k8s.io/apiserver/pkg/authentication/token/cache"
|
|
webhooktoken "k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
|
authenticationclient "k8s.io/client-go/kubernetes/typed/authentication/v1"
|
|
)
|
|
|
|
// DelegatingAuthenticatorConfig is the minimal configuration needed to create an authenticator
|
|
// built to delegate authentication to a kube API server
|
|
type DelegatingAuthenticatorConfig struct {
|
|
Anonymous bool
|
|
|
|
// TokenAccessReviewClient is a client to do token review. It can be nil. Then every token is ignored.
|
|
TokenAccessReviewClient authenticationclient.TokenReviewInterface
|
|
|
|
// CacheTTL is the length of time that a token authentication answer will be cached.
|
|
CacheTTL time.Duration
|
|
|
|
// CAContentProvider are the options for verifying incoming connections using mTLS and directly assigning to users.
|
|
// Generally this is the CA bundle file used to authenticate client certificates
|
|
// If this is nil, then mTLS will not be used.
|
|
ClientCertificateCAContentProvider CAContentProvider
|
|
|
|
APIAudiences authenticator.Audiences
|
|
|
|
RequestHeaderConfig *RequestHeaderConfig
|
|
}
|
|
|
|
func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) {
|
|
authenticators := []authenticator.Request{}
|
|
securityDefinitions := spec.SecurityDefinitions{}
|
|
|
|
// front-proxy first, then remote
|
|
// Add the front proxy authenticator if requested
|
|
if c.RequestHeaderConfig != nil {
|
|
requestHeaderAuthenticator := headerrequest.NewDynamicVerifyOptionsSecure(
|
|
c.RequestHeaderConfig.CAContentProvider.VerifyOptions,
|
|
c.RequestHeaderConfig.AllowedClientNames,
|
|
c.RequestHeaderConfig.UsernameHeaders,
|
|
c.RequestHeaderConfig.GroupHeaders,
|
|
c.RequestHeaderConfig.ExtraHeaderPrefixes,
|
|
)
|
|
authenticators = append(authenticators, requestHeaderAuthenticator)
|
|
}
|
|
|
|
// x509 client cert auth
|
|
if c.ClientCertificateCAContentProvider != nil {
|
|
authenticators = append(authenticators, x509.NewDynamic(c.ClientCertificateCAContentProvider.VerifyOptions, x509.CommonNameUserConversion))
|
|
}
|
|
|
|
if c.TokenAccessReviewClient != nil {
|
|
tokenAuth, err := webhooktoken.NewFromInterface(c.TokenAccessReviewClient, c.APIAudiences)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
cachingTokenAuth := cache.New(context.TODO(), tokenAuth, false, c.CacheTTL, c.CacheTTL)
|
|
authenticators = append(authenticators, bearertoken.New(cachingTokenAuth), websocket.NewProtocolAuthenticator(cachingTokenAuth))
|
|
|
|
securityDefinitions["BearerToken"] = &spec.SecurityScheme{
|
|
SecuritySchemeProps: spec.SecuritySchemeProps{
|
|
Type: "apiKey",
|
|
Name: "authorization",
|
|
In: "header",
|
|
Description: "Bearer Token authentication",
|
|
},
|
|
}
|
|
}
|
|
|
|
if len(authenticators) == 0 {
|
|
if c.Anonymous {
|
|
return anonymous.NewAuthenticator(), &securityDefinitions, nil
|
|
}
|
|
return nil, nil, errors.New("No authentication method configured")
|
|
}
|
|
|
|
authenticator := group.NewAuthenticatedGroupAdder(unionauth.New(authenticators...))
|
|
if c.Anonymous {
|
|
authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
|
}
|
|
return authenticator, &securityDefinitions, nil
|
|
}
|