mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #89069 from enj/enj/i/drop_password_file
Remove support for basic authentication
This commit is contained in:
commit
f899ad704a
@ -101,9 +101,6 @@ function start-kube-apiserver {
|
|||||||
params+=" --service-account-key-file=${SERVICEACCOUNT_CERT_PATH}"
|
params+=" --service-account-key-file=${SERVICEACCOUNT_CERT_PATH}"
|
||||||
fi
|
fi
|
||||||
params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
|
params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
|
||||||
if [[ -n "${KUBE_PASSWORD:-}" && -n "${KUBE_USER:-}" ]]; then
|
|
||||||
params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT_SEC:-}" ]]; then
|
if [[ -n "${KUBE_APISERVER_REQUEST_TIMEOUT_SEC:-}" ]]; then
|
||||||
params+=" --request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT_SEC}s"
|
params+=" --request-timeout=${KUBE_APISERVER_REQUEST_TIMEOUT_SEC}s"
|
||||||
|
@ -37,7 +37,7 @@ import (
|
|||||||
// BuildHandlerChain builds a handler chain with a base handler and CompletedConfig.
|
// BuildHandlerChain builds a handler chain with a base handler and CompletedConfig.
|
||||||
func BuildHandlerChain(apiHandler http.Handler, authorizationInfo *apiserver.AuthorizationInfo, authenticationInfo *apiserver.AuthenticationInfo) http.Handler {
|
func BuildHandlerChain(apiHandler http.Handler, authorizationInfo *apiserver.AuthorizationInfo, authenticationInfo *apiserver.AuthenticationInfo) http.Handler {
|
||||||
requestInfoResolver := &apirequest.RequestInfoFactory{}
|
requestInfoResolver := &apirequest.RequestInfoFactory{}
|
||||||
failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs, false)
|
failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs)
|
||||||
|
|
||||||
handler := apiHandler
|
handler := apiHandler
|
||||||
if authorizationInfo != nil {
|
if authorizationInfo != nil {
|
||||||
|
@ -276,7 +276,6 @@ func TestAddFlags(t *testing.T) {
|
|||||||
UsernameClaim: "sub",
|
UsernameClaim: "sub",
|
||||||
SigningAlgs: []string{"RS256"},
|
SigningAlgs: []string{"RS256"},
|
||||||
},
|
},
|
||||||
PasswordFile: &kubeoptions.PasswordFileAuthenticationOptions{},
|
|
||||||
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
|
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{},
|
||||||
ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
|
ServiceAccounts: &kubeoptions.ServiceAccountAuthenticationOptions{
|
||||||
Lookup: true,
|
Lookup: true,
|
||||||
|
@ -262,7 +262,7 @@ func Run(ctx context.Context, cc schedulerserverconfig.CompletedConfig, outOfTre
|
|||||||
// buildHandlerChain wraps the given handler with the standard filters.
|
// buildHandlerChain wraps the given handler with the standard filters.
|
||||||
func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz authorizer.Authorizer) http.Handler {
|
func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz authorizer.Authorizer) http.Handler {
|
||||||
requestInfoResolver := &apirequest.RequestInfoFactory{}
|
requestInfoResolver := &apirequest.RequestInfoFactory{}
|
||||||
failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs, false)
|
failedHandler := genericapifilters.Unauthorized(legacyscheme.Codecs)
|
||||||
|
|
||||||
handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
|
handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
|
||||||
handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
|
handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
|
||||||
|
@ -27,8 +27,6 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/plugin/pkg/client/auth:go_default_library",
|
"//staging/src/k8s.io/client-go/plugin/pkg/client/auth:go_default_library",
|
||||||
|
@ -36,8 +36,6 @@ import (
|
|||||||
tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
|
tokenunion "k8s.io/apiserver/pkg/authentication/token/union"
|
||||||
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
"k8s.io/apiserver/pkg/server/dynamiccertificates"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile"
|
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth"
|
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
||||||
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/webhook"
|
||||||
|
|
||||||
@ -51,7 +49,6 @@ import (
|
|||||||
// Config contains the data on how to authenticate a request to the Kube API Server
|
// Config contains the data on how to authenticate a request to the Kube API Server
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Anonymous bool
|
Anonymous bool
|
||||||
BasicAuthFile string
|
|
||||||
BootstrapToken bool
|
BootstrapToken bool
|
||||||
|
|
||||||
TokenAuthFile string
|
TokenAuthFile string
|
||||||
@ -109,22 +106,6 @@ func (config Config) New() (authenticator.Request, *spec.SecurityDefinitions, er
|
|||||||
authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator))
|
authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator))
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic auth
|
|
||||||
if len(config.BasicAuthFile) > 0 {
|
|
||||||
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, basicAuth))
|
|
||||||
|
|
||||||
securityDefinitions["HTTPBasic"] = &spec.SecurityScheme{
|
|
||||||
SecuritySchemeProps: spec.SecuritySchemeProps{
|
|
||||||
Type: "basic",
|
|
||||||
Description: "HTTP Basic authentication",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// X509 methods
|
// X509 methods
|
||||||
if config.ClientCAContentProvider != nil {
|
if config.ClientCAContentProvider != nil {
|
||||||
certAuth := x509.NewDynamic(config.ClientCAContentProvider.VerifyOptions, x509.CommonNameUserConversion)
|
certAuth := x509.NewDynamic(config.ClientCAContentProvider.VerifyOptions, x509.CommonNameUserConversion)
|
||||||
@ -235,16 +216,6 @@ func IsValidServiceAccountKeyFile(file string) bool {
|
|||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newAuthenticatorFromBasicAuthFile returns an authenticator.Request or an error
|
|
||||||
func newAuthenticatorFromBasicAuthFile(basicAuthFile string) (authenticator.Request, error) {
|
|
||||||
basicAuthenticator, err := passwordfile.NewCSV(basicAuthFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return basicauth.New(basicAuthenticator), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// newAuthenticatorFromTokenFile returns an authenticator.Token or an error
|
// newAuthenticatorFromTokenFile returns an authenticator.Token or an error
|
||||||
func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Token, error) {
|
func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Token, error) {
|
||||||
tokenAuthenticator, err := tokenfile.NewCSV(tokenAuthFile)
|
tokenAuthenticator, err := tokenfile.NewCSV(tokenAuthFile)
|
||||||
|
@ -43,7 +43,6 @@ type BuiltInAuthenticationOptions struct {
|
|||||||
BootstrapToken *BootstrapTokenAuthenticationOptions
|
BootstrapToken *BootstrapTokenAuthenticationOptions
|
||||||
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
ClientCert *genericoptions.ClientCertAuthenticationOptions
|
||||||
OIDC *OIDCAuthenticationOptions
|
OIDC *OIDCAuthenticationOptions
|
||||||
PasswordFile *PasswordFileAuthenticationOptions
|
|
||||||
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
|
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
|
||||||
ServiceAccounts *ServiceAccountAuthenticationOptions
|
ServiceAccounts *ServiceAccountAuthenticationOptions
|
||||||
TokenFile *TokenFileAuthenticationOptions
|
TokenFile *TokenFileAuthenticationOptions
|
||||||
@ -73,10 +72,6 @@ type OIDCAuthenticationOptions struct {
|
|||||||
RequiredClaims map[string]string
|
RequiredClaims map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PasswordFileAuthenticationOptions struct {
|
|
||||||
BasicAuthFile string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceAccountAuthenticationOptions struct {
|
type ServiceAccountAuthenticationOptions struct {
|
||||||
KeyFiles []string
|
KeyFiles []string
|
||||||
Lookup bool
|
Lookup bool
|
||||||
@ -108,7 +103,6 @@ func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
|
|||||||
WithBootstrapToken().
|
WithBootstrapToken().
|
||||||
WithClientCert().
|
WithClientCert().
|
||||||
WithOIDC().
|
WithOIDC().
|
||||||
WithPasswordFile().
|
|
||||||
WithRequestHeader().
|
WithRequestHeader().
|
||||||
WithServiceAccounts().
|
WithServiceAccounts().
|
||||||
WithTokenFile().
|
WithTokenFile().
|
||||||
@ -135,11 +129,6 @@ func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
|
|
||||||
s.PasswordFile = &PasswordFileAuthenticationOptions{}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
|
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
|
||||||
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
|
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
|
||||||
return s
|
return s
|
||||||
@ -274,13 +263,6 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
|||||||
"Repeat this flag to specify multiple claims.")
|
"Repeat this flag to specify multiple claims.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.PasswordFile != nil {
|
|
||||||
fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
|
|
||||||
"If set, the file that will be used to admit requests to the secure port of the API server "+
|
|
||||||
"via http basic authentication.")
|
|
||||||
fs.MarkDeprecated("basic-auth-file", "Basic authentication mode is deprecated and will be removed in a future release. It is not recommended for production environments.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.RequestHeader != nil {
|
if s.RequestHeader != nil {
|
||||||
s.RequestHeader.AddFlags(fs)
|
s.RequestHeader.AddFlags(fs)
|
||||||
}
|
}
|
||||||
@ -377,10 +359,6 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticat
|
|||||||
ret.OIDCRequiredClaims = s.OIDC.RequiredClaims
|
ret.OIDCRequiredClaims = s.OIDC.RequiredClaims
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.PasswordFile != nil {
|
|
||||||
ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.RequestHeader != nil {
|
if s.RequestHeader != nil {
|
||||||
var err error
|
var err error
|
||||||
ret.RequestHeaderConfig, err = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
|
ret.RequestHeaderConfig, err = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
|
||||||
@ -447,8 +425,6 @@ func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Authentication.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0
|
|
||||||
|
|
||||||
c.Authentication.APIAudiences = o.APIAudiences
|
c.Authentication.APIAudiences = o.APIAudiences
|
||||||
if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
|
if o.ServiceAccounts != nil && o.ServiceAccounts.Issuer != "" && len(o.APIAudiences) == 0 {
|
||||||
c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
|
c.Authentication.APIAudiences = authenticator.Audiences{o.ServiceAccounts.Issuer}
|
||||||
|
@ -120,9 +120,6 @@ func TestToAuthenticationConfig(t *testing.T) {
|
|||||||
IssuerURL: "testIssuerURL",
|
IssuerURL: "testIssuerURL",
|
||||||
ClientID: "testClientID",
|
ClientID: "testClientID",
|
||||||
},
|
},
|
||||||
PasswordFile: &PasswordFileAuthenticationOptions{
|
|
||||||
BasicAuthFile: "/testBasicAuthFile",
|
|
||||||
},
|
|
||||||
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{
|
RequestHeader: &apiserveroptions.RequestHeaderAuthenticationOptions{
|
||||||
UsernameHeaders: []string{"x-remote-user"},
|
UsernameHeaders: []string{"x-remote-user"},
|
||||||
GroupHeaders: []string{"x-remote-group"},
|
GroupHeaders: []string{"x-remote-group"},
|
||||||
@ -144,7 +141,6 @@ func TestToAuthenticationConfig(t *testing.T) {
|
|||||||
expectConfig := kubeauthenticator.Config{
|
expectConfig := kubeauthenticator.Config{
|
||||||
APIAudiences: authenticator.Audiences{"http://foo.bar.com"},
|
APIAudiences: authenticator.Audiences{"http://foo.bar.com"},
|
||||||
Anonymous: false,
|
Anonymous: false,
|
||||||
BasicAuthFile: "/testBasicAuthFile",
|
|
||||||
BootstrapToken: false,
|
BootstrapToken: false,
|
||||||
ClientCAContentProvider: nil, // this is nil because you can't compare functions
|
ClientCAContentProvider: nil, // this is nil because you can't compare functions
|
||||||
TokenAuthFile: "/testTokenFile",
|
TokenAuthFile: "/testTokenFile",
|
||||||
|
@ -35,13 +35,6 @@ type Request interface {
|
|||||||
AuthenticateRequest(req *http.Request) (*Response, bool, error)
|
AuthenticateRequest(req *http.Request) (*Response, bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Password checks a username and password against a backing authentication
|
|
||||||
// store and returns a Response or an error if the password could not be
|
|
||||||
// checked.
|
|
||||||
type Password interface {
|
|
||||||
AuthenticatePassword(ctx context.Context, user, password string) (*Response, bool, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenFunc is a function that implements the Token interface.
|
// TokenFunc is a function that implements the Token interface.
|
||||||
type TokenFunc func(ctx context.Context, token string) (*Response, bool, error)
|
type TokenFunc func(ctx context.Context, token string) (*Response, bool, error)
|
||||||
|
|
||||||
@ -58,14 +51,6 @@ func (f RequestFunc) AuthenticateRequest(req *http.Request) (*Response, bool, er
|
|||||||
return f(req)
|
return f(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordFunc is a function that implements the Password interface.
|
|
||||||
type PasswordFunc func(ctx context.Context, user, password string) (*Response, bool, error)
|
|
||||||
|
|
||||||
// AuthenticatePassword implements authenticator.Password.
|
|
||||||
func (f PasswordFunc) AuthenticatePassword(ctx context.Context, user, password string) (*Response, bool, error) {
|
|
||||||
return f(ctx, user, password)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response is the struct returned by authenticator interfaces upon successful
|
// Response is the struct returned by authenticator interfaces upon successful
|
||||||
// authentication. It contains information about whether the authenticator
|
// authentication. It contains information about whether the authenticator
|
||||||
// authenticated the request, information about the context of the
|
// authenticated the request, information about the context of the
|
||||||
|
@ -71,11 +71,8 @@ func WithAuthentication(handler http.Handler, auth authenticator.Request, failed
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Unauthorized(s runtime.NegotiatedSerializer, supportsBasicAuth bool) http.Handler {
|
func Unauthorized(s runtime.NegotiatedSerializer) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
if supportsBasicAuth {
|
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="kubernetes-master"`)
|
|
||||||
}
|
|
||||||
ctx := req.Context()
|
ctx := req.Context()
|
||||||
requestInfo, found := genericapirequest.RequestInfoFrom(ctx)
|
requestInfo, found := genericapirequest.RequestInfoFrom(ctx)
|
||||||
if !found {
|
if !found {
|
||||||
|
@ -272,10 +272,6 @@ type AuthenticationInfo struct {
|
|||||||
APIAudiences authenticator.Audiences
|
APIAudiences authenticator.Audiences
|
||||||
// Authenticator determines which subject is making the request
|
// Authenticator determines which subject is making the request
|
||||||
Authenticator authenticator.Request
|
Authenticator authenticator.Request
|
||||||
// SupportsBasicAuth indicates that's at least one Authenticator supports basic auth
|
|
||||||
// If this is true, a basic auth challenge is returned on authentication failure
|
|
||||||
// TODO(roberthbailey): Remove once the server no longer supports http basic auth.
|
|
||||||
SupportsBasicAuth bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorizationInfo struct {
|
type AuthorizationInfo struct {
|
||||||
@ -670,7 +666,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
|||||||
}
|
}
|
||||||
handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
|
handler = genericapifilters.WithImpersonation(handler, c.Authorization.Authorizer, c.Serializer)
|
||||||
handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
|
handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc)
|
||||||
failedHandler := genericapifilters.Unauthorized(c.Serializer, c.Authentication.SupportsBasicAuth)
|
failedHandler := genericapifilters.Unauthorized(c.Serializer)
|
||||||
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
|
failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker)
|
||||||
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
|
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
|
||||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||||
|
@ -319,7 +319,6 @@ func (s *DelegatingAuthenticationOptions) ApplyTo(authenticationInfo *server.Aut
|
|||||||
if openAPIConfig != nil {
|
if openAPIConfig != nil {
|
||||||
openAPIConfig.SecurityDefinitions = securityDefinitions
|
openAPIConfig.SecurityDefinitions = securityDefinitions
|
||||||
}
|
}
|
||||||
authenticationInfo.SupportsBasicAuth = false
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@ filegroup(
|
|||||||
name = "all-srcs",
|
name = "all-srcs",
|
||||||
srcs = [
|
srcs = [
|
||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:all-srcs",
|
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:all-srcs",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/oidc:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:all-srcs",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest:all-srcs",
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:all-srcs",
|
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook:all-srcs",
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["doc.go"],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/password",
|
|
||||||
importpath = "k8s.io/apiserver/plugin/pkg/authenticator/password",
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [
|
|
||||||
":package-srcs",
|
|
||||||
"//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:all-srcs",
|
|
||||||
],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 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 password contains authenticator.Password implementations
|
|
||||||
package password // import "k8s.io/apiserver/plugin/pkg/authenticator/password"
|
|
@ -1,39 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
"go_test",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = ["passwordfile_test.go"],
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = ["//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library"],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["passwordfile.go"],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile",
|
|
||||||
importpath = "k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile",
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 passwordfile
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/subtle"
|
|
||||||
"encoding/csv"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/klog"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PasswordAuthenticator authenticates users by password
|
|
||||||
type PasswordAuthenticator struct {
|
|
||||||
users map[string]*userPasswordInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
type userPasswordInfo struct {
|
|
||||||
info *user.DefaultInfo
|
|
||||||
password string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCSV returns a PasswordAuthenticator, populated from a CSV file.
|
|
||||||
// The CSV file must contain records in the format "password,username,useruid"
|
|
||||||
func NewCSV(path string) (*PasswordAuthenticator, error) {
|
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
recordNum := 0
|
|
||||||
users := make(map[string]*userPasswordInfo)
|
|
||||||
reader := csv.NewReader(file)
|
|
||||||
reader.FieldsPerRecord = -1
|
|
||||||
for {
|
|
||||||
record, err := reader.Read()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(record) < 3 {
|
|
||||||
return nil, fmt.Errorf("password file '%s' must have at least 3 columns (password, user name, user uid), found %d", path, len(record))
|
|
||||||
}
|
|
||||||
obj := &userPasswordInfo{
|
|
||||||
info: &user.DefaultInfo{Name: record[1], UID: record[2]},
|
|
||||||
password: record[0],
|
|
||||||
}
|
|
||||||
if len(record) >= 4 {
|
|
||||||
obj.info.Groups = strings.Split(record[3], ",")
|
|
||||||
}
|
|
||||||
recordNum++
|
|
||||||
if _, exist := users[obj.info.Name]; exist {
|
|
||||||
klog.Warningf("duplicate username '%s' has been found in password file '%s', record number '%d'", obj.info.Name, path, recordNum)
|
|
||||||
}
|
|
||||||
users[obj.info.Name] = obj
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PasswordAuthenticator{users}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// AuthenticatePassword returns user info if authentication is successful, nil otherwise
|
|
||||||
func (a *PasswordAuthenticator) AuthenticatePassword(ctx context.Context, username, password string) (*authenticator.Response, bool, error) {
|
|
||||||
user, ok := a.users[username]
|
|
||||||
if !ok {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
if subtle.ConstantTimeCompare([]byte(user.password), []byte(password)) == 0 {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
return &authenticator.Response{User: user.info}, true, nil
|
|
||||||
}
|
|
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 passwordfile
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestPasswordFile(t *testing.T) {
|
|
||||||
auth, err := newWithContents(t, `
|
|
||||||
password1,user1,uid1
|
|
||||||
password2,user2,uid2
|
|
||||||
password3,user3,uid3,"group1,group2"
|
|
||||||
password4,user4,uid4,"group2"
|
|
||||||
password5,user5,uid5,group5
|
|
||||||
password6,user6,uid6,group5,otherdata
|
|
||||||
password7,user7,uid7,"group1,group2",otherdata
|
|
||||||
`)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unable to read passwordfile: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
testCases := []struct {
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
User *user.DefaultInfo
|
|
||||||
Ok bool
|
|
||||||
Err bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
Username: "user1",
|
|
||||||
Password: "password1",
|
|
||||||
User: &user.DefaultInfo{Name: "user1", UID: "uid1"},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user2",
|
|
||||||
Password: "password2",
|
|
||||||
User: &user.DefaultInfo{Name: "user2", UID: "uid2"},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user1",
|
|
||||||
Password: "password2",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user2",
|
|
||||||
Password: "password1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user3",
|
|
||||||
Password: "password3",
|
|
||||||
User: &user.DefaultInfo{Name: "user3", UID: "uid3", Groups: []string{"group1", "group2"}},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user4",
|
|
||||||
Password: "password4",
|
|
||||||
User: &user.DefaultInfo{Name: "user4", UID: "uid4", Groups: []string{"group2"}},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user5",
|
|
||||||
Password: "password5",
|
|
||||||
User: &user.DefaultInfo{Name: "user5", UID: "uid5", Groups: []string{"group5"}},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user6",
|
|
||||||
Password: "password6",
|
|
||||||
User: &user.DefaultInfo{Name: "user6", UID: "uid6", Groups: []string{"group5"}},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user7",
|
|
||||||
Password: "password7",
|
|
||||||
User: &user.DefaultInfo{Name: "user7", UID: "uid7", Groups: []string{"group1", "group2"}},
|
|
||||||
Ok: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user7",
|
|
||||||
Password: "passwordbad",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "userbad",
|
|
||||||
Password: "password7",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Username: "user8",
|
|
||||||
Password: "password8",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for i, testCase := range testCases {
|
|
||||||
resp, ok, err := auth.AuthenticatePassword(context.Background(), testCase.Username, testCase.Password)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("%d: unexpected error: %v", i, err)
|
|
||||||
}
|
|
||||||
if testCase.User == nil {
|
|
||||||
if resp != nil {
|
|
||||||
t.Errorf("%d: unexpected non-nil user %#v", i, resp.User)
|
|
||||||
}
|
|
||||||
} else if !reflect.DeepEqual(testCase.User, resp.User) {
|
|
||||||
t.Errorf("%d: expected user %#v, got %#v", i, testCase.User, resp.User)
|
|
||||||
}
|
|
||||||
if testCase.Ok != ok {
|
|
||||||
t.Errorf("%d: expected auth %v, got %v", i, testCase.Ok, ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBadPasswordFile(t *testing.T) {
|
|
||||||
if _, err := newWithContents(t, `
|
|
||||||
password1,user1,uid1
|
|
||||||
password2,user2,uid2
|
|
||||||
password3,user3
|
|
||||||
password4
|
|
||||||
`); err == nil {
|
|
||||||
t.Fatalf("unexpected non error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInsufficientColumnsPasswordFile(t *testing.T) {
|
|
||||||
if _, err := newWithContents(t, "password4\n"); err == nil {
|
|
||||||
t.Fatalf("unexpected non error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newWithContents(t *testing.T, contents string) (auth *PasswordAuthenticator, err error) {
|
|
||||||
f, err := ioutil.TempFile("", "passwordfile_test")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error creating passwordfile: %v", err)
|
|
||||||
}
|
|
||||||
f.Close()
|
|
||||||
defer os.Remove(f.Name())
|
|
||||||
|
|
||||||
if err := ioutil.WriteFile(f.Name(), []byte(contents), 0700); err != nil {
|
|
||||||
t.Fatalf("unexpected error writing passwordfile: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewCSV(f.Name())
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
"go_test",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = ["basicauth_test.go"],
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = [
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = ["basicauth.go"],
|
|
||||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth",
|
|
||||||
importpath = "k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth",
|
|
||||||
deps = ["//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 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 basicauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Authenticator authenticates requests using basic auth
|
|
||||||
type Authenticator struct {
|
|
||||||
auth authenticator.Password
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a request authenticator that validates credentials using the provided password authenticator
|
|
||||||
func New(auth authenticator.Password) *Authenticator {
|
|
||||||
return &Authenticator{auth}
|
|
||||||
}
|
|
||||||
|
|
||||||
var errInvalidAuth = errors.New("invalid username/password combination")
|
|
||||||
|
|
||||||
// AuthenticateRequest authenticates the request using the "Authorization: Basic" header in the request
|
|
||||||
func (a *Authenticator) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {
|
|
||||||
username, password, found := req.BasicAuth()
|
|
||||||
if !found {
|
|
||||||
return nil, false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, ok, err := a.auth.AuthenticatePassword(req.Context(), username, password)
|
|
||||||
|
|
||||||
// If the password authenticator didn't error, provide a default error
|
|
||||||
if !ok && err == nil {
|
|
||||||
err = errInvalidAuth
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp, ok, err
|
|
||||||
}
|
|
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2014 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 basicauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
type testPassword struct {
|
|
||||||
Username string
|
|
||||||
Password string
|
|
||||||
Called bool
|
|
||||||
|
|
||||||
User user.Info
|
|
||||||
OK bool
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *testPassword) AuthenticatePassword(ctx context.Context, user, password string) (*authenticator.Response, bool, error) {
|
|
||||||
t.Called = true
|
|
||||||
t.Username = user
|
|
||||||
t.Password = password
|
|
||||||
return &authenticator.Response{User: t.User}, t.OK, t.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBasicAuth(t *testing.T) {
|
|
||||||
testCases := map[string]struct {
|
|
||||||
Header string
|
|
||||||
Password testPassword
|
|
||||||
|
|
||||||
ExpectedCalled bool
|
|
||||||
ExpectedUsername string
|
|
||||||
ExpectedPassword string
|
|
||||||
|
|
||||||
ExpectedUser string
|
|
||||||
ExpectedOK bool
|
|
||||||
ExpectedErr bool
|
|
||||||
}{
|
|
||||||
"no auth": {},
|
|
||||||
"empty password basic header": {
|
|
||||||
ExpectedCalled: true,
|
|
||||||
ExpectedUsername: "user_with_empty_password",
|
|
||||||
ExpectedPassword: "",
|
|
||||||
ExpectedErr: true,
|
|
||||||
},
|
|
||||||
"valid basic header": {
|
|
||||||
ExpectedCalled: true,
|
|
||||||
ExpectedUsername: "myuser",
|
|
||||||
ExpectedPassword: "mypassword:withcolon",
|
|
||||||
ExpectedErr: true,
|
|
||||||
},
|
|
||||||
"password auth returned user": {
|
|
||||||
Password: testPassword{User: &user.DefaultInfo{Name: "returneduser"}, OK: true},
|
|
||||||
ExpectedCalled: true,
|
|
||||||
ExpectedUsername: "myuser",
|
|
||||||
ExpectedPassword: "mypw",
|
|
||||||
ExpectedUser: "returneduser",
|
|
||||||
ExpectedOK: true,
|
|
||||||
},
|
|
||||||
"password auth returned error": {
|
|
||||||
Password: testPassword{Err: errors.New("auth error")},
|
|
||||||
ExpectedCalled: true,
|
|
||||||
ExpectedUsername: "myuser",
|
|
||||||
ExpectedPassword: "mypw",
|
|
||||||
ExpectedErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, testCase := range testCases {
|
|
||||||
password := testCase.Password
|
|
||||||
auth := authenticator.Request(New(&password))
|
|
||||||
|
|
||||||
req, _ := http.NewRequest("GET", "/", nil)
|
|
||||||
if testCase.ExpectedUsername != "" || testCase.ExpectedPassword != "" {
|
|
||||||
req.SetBasicAuth(testCase.ExpectedUsername, testCase.ExpectedPassword)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, ok, err := auth.AuthenticateRequest(req)
|
|
||||||
|
|
||||||
if testCase.ExpectedCalled != password.Called {
|
|
||||||
t.Errorf("%s: Expected called=%v, got %v", k, testCase.ExpectedCalled, password.Called)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if testCase.ExpectedUsername != password.Username {
|
|
||||||
t.Errorf("%s: Expected called with username=%v, got %v", k, testCase.ExpectedUsername, password.Username)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if testCase.ExpectedPassword != password.Password {
|
|
||||||
t.Errorf("%s: Expected called with password=%v, got %v", k, testCase.ExpectedPassword, password.Password)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if testCase.ExpectedErr != (err != nil) {
|
|
||||||
t.Errorf("%s: Expected err=%v, got err=%v", k, testCase.ExpectedErr, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if testCase.ExpectedOK != ok {
|
|
||||||
t.Errorf("%s: Expected ok=%v, got ok=%v", k, testCase.ExpectedOK, ok)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if testCase.ExpectedUser != "" && testCase.ExpectedUser != resp.User.GetName() {
|
|
||||||
t.Errorf("%s: Expected user.GetName()=%v, got %v", k, testCase.ExpectedUser, resp.User.GetName())
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,7 @@ spec:
|
|||||||
- /usr/local/bin/kube-apiserver --address=127.0.0.1 --etcd-servers=http://127.0.0.1:4001
|
- /usr/local/bin/kube-apiserver --address=127.0.0.1 --etcd-servers=http://127.0.0.1:4001
|
||||||
--cloud-provider=gce --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
|
--cloud-provider=gce --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
|
||||||
--service-cluster-ip-range=10.0.0.0/16 --client-ca-file=/srv/kubernetes/ca.crt
|
--service-cluster-ip-range=10.0.0.0/16 --client-ca-file=/srv/kubernetes/ca.crt
|
||||||
--basic-auth-file=/srv/kubernetes/basic_auth.csv --cluster-name=e2e-test-bburns
|
--cluster-name=e2e-test-bburns
|
||||||
--tls-cert-file=/srv/kubernetes/server.cert --tls-private-key-file=/srv/kubernetes/server.key
|
--tls-cert-file=/srv/kubernetes/server.cert --tls-private-key-file=/srv/kubernetes/server.key
|
||||||
--secure-port=443 --token-auth-file=/srv/kubernetes/known_tokens.csv --v=2
|
--secure-port=443 --token-auth-file=/srv/kubernetes/known_tokens.csv --v=2
|
||||||
--allow-privileged=False 1>>/var/log/kube-apiserver.log 2>&1
|
--allow-privileged=False 1>>/var/log/kube-apiserver.log 2>&1
|
||||||
|
@ -547,7 +547,6 @@ function compute-kube-apiserver-params {
|
|||||||
params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt"
|
params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt"
|
||||||
params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
|
params+=" --token-auth-file=/etc/srv/kubernetes/known_tokens.csv"
|
||||||
params+=" --secure-port=443"
|
params+=" --secure-port=443"
|
||||||
params+=" --basic-auth-file=/etc/srv/kubernetes/basic_auth.csv"
|
|
||||||
params+=" --target-ram-mb=$((NUM_NODES * 60))"
|
params+=" --target-ram-mb=$((NUM_NODES * 60))"
|
||||||
params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
|
params+=" --service-cluster-ip-range=${SERVICE_CLUSTER_IP_RANGE}"
|
||||||
params+=" --admission-control=${CUSTOM_ADMISSION_PLUGINS}"
|
params+=" --admission-control=${CUSTOM_ADMISSION_PLUGINS}"
|
||||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -1401,8 +1401,6 @@ k8s.io/apiserver/plugin/pkg/audit/dynamic/enforced
|
|||||||
k8s.io/apiserver/plugin/pkg/audit/log
|
k8s.io/apiserver/plugin/pkg/audit/log
|
||||||
k8s.io/apiserver/plugin/pkg/audit/truncate
|
k8s.io/apiserver/plugin/pkg/audit/truncate
|
||||||
k8s.io/apiserver/plugin/pkg/audit/webhook
|
k8s.io/apiserver/plugin/pkg/audit/webhook
|
||||||
k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile
|
|
||||||
k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth
|
|
||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
|
k8s.io/apiserver/plugin/pkg/authenticator/token/oidc
|
||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
|
k8s.io/apiserver/plugin/pkg/authenticator/token/tokentest
|
||||||
k8s.io/apiserver/plugin/pkg/authenticator/token/webhook
|
k8s.io/apiserver/plugin/pkg/authenticator/token/webhook
|
||||||
|
Loading…
Reference in New Issue
Block a user