mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
Add anonymous auth to the auth chain
This commit is contained in:
parent
174e454874
commit
0c36c5e556
@ -201,6 +201,7 @@ func Run(s *options.APIServer) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apiAuthenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
apiAuthenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
||||||
|
Anonymous: s.AnonymousAuth,
|
||||||
BasicAuthFile: s.BasicAuthFile,
|
BasicAuthFile: s.BasicAuthFile,
|
||||||
ClientCAFile: s.ClientCAFile,
|
ClientCAFile: s.ClientCAFile,
|
||||||
TokenAuthFile: s.TokenAuthFile,
|
TokenAuthFile: s.TokenAuthFile,
|
||||||
|
@ -115,6 +115,7 @@ func Run(s *options.ServerRunOptions) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apiAuthenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
apiAuthenticator, err := authenticator.New(authenticator.AuthenticatorConfig{
|
||||||
|
Anonymous: s.AnonymousAuth,
|
||||||
BasicAuthFile: s.BasicAuthFile,
|
BasicAuthFile: s.BasicAuthFile,
|
||||||
ClientCAFile: s.ClientCAFile,
|
ClientCAFile: s.ClientCAFile,
|
||||||
TokenAuthFile: s.TokenAuthFile,
|
TokenAuthFile: s.TokenAuthFile,
|
||||||
|
@ -9,6 +9,7 @@ all-namespaces
|
|||||||
allocate-node-cidrs
|
allocate-node-cidrs
|
||||||
allow-privileged
|
allow-privileged
|
||||||
allowed-not-ready-nodes
|
allowed-not-ready-nodes
|
||||||
|
anonymous-auth
|
||||||
api-advertise-addresses
|
api-advertise-addresses
|
||||||
api-external-dns-names
|
api-external-dns-names
|
||||||
api-burst
|
api-burst
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
certutil "k8s.io/kubernetes/pkg/util/cert"
|
certutil "k8s.io/kubernetes/pkg/util/cert"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/keystone"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/keystone"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
|
||||||
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/anonymous"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
|
||||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509"
|
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509"
|
||||||
@ -36,6 +37,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type AuthenticatorConfig struct {
|
type AuthenticatorConfig struct {
|
||||||
|
Anonymous bool
|
||||||
BasicAuthFile string
|
BasicAuthFile string
|
||||||
ClientCAFile string
|
ClientCAFile string
|
||||||
TokenAuthFile string
|
TokenAuthFile string
|
||||||
@ -57,6 +59,7 @@ type AuthenticatorConfig struct {
|
|||||||
func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
||||||
var authenticators []authenticator.Request
|
var authenticators []authenticator.Request
|
||||||
|
|
||||||
|
// BasicAuth methods, local first, then remote
|
||||||
if len(config.BasicAuthFile) > 0 {
|
if len(config.BasicAuthFile) > 0 {
|
||||||
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
|
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -64,7 +67,15 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
}
|
}
|
||||||
authenticators = append(authenticators, basicAuth)
|
authenticators = append(authenticators, basicAuth)
|
||||||
}
|
}
|
||||||
|
if len(config.KeystoneURL) > 0 {
|
||||||
|
keystoneAuth, err := newAuthenticatorFromKeystoneURL(config.KeystoneURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
authenticators = append(authenticators, keystoneAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
// X509 methods
|
||||||
if len(config.ClientCAFile) > 0 {
|
if len(config.ClientCAFile) > 0 {
|
||||||
certAuth, err := newAuthenticatorFromClientCAFile(config.ClientCAFile)
|
certAuth, err := newAuthenticatorFromClientCAFile(config.ClientCAFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -73,6 +84,7 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
authenticators = append(authenticators, certAuth)
|
authenticators = append(authenticators, certAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bearer token methods, local first, then remote
|
||||||
if len(config.TokenAuthFile) > 0 {
|
if len(config.TokenAuthFile) > 0 {
|
||||||
tokenAuth, err := newAuthenticatorFromTokenFile(config.TokenAuthFile)
|
tokenAuth, err := newAuthenticatorFromTokenFile(config.TokenAuthFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -80,7 +92,6 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
}
|
}
|
||||||
authenticators = append(authenticators, tokenAuth)
|
authenticators = append(authenticators, tokenAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.ServiceAccountKeyFile) > 0 {
|
if len(config.ServiceAccountKeyFile) > 0 {
|
||||||
serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountKeyFile, config.ServiceAccountLookup, config.ServiceAccountTokenGetter)
|
serviceAccountAuth, err := newServiceAccountAuthenticator(config.ServiceAccountKeyFile, config.ServiceAccountLookup, config.ServiceAccountTokenGetter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -88,7 +99,6 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
}
|
}
|
||||||
authenticators = append(authenticators, serviceAccountAuth)
|
authenticators = append(authenticators, serviceAccountAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(ericchiang): Keep the OpenID Connect after Service Accounts.
|
// NOTE(ericchiang): Keep the OpenID Connect after Service Accounts.
|
||||||
//
|
//
|
||||||
// Because both plugins verify JWTs whichever comes first in the union experiences
|
// Because both plugins verify JWTs whichever comes first in the union experiences
|
||||||
@ -102,15 +112,6 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
}
|
}
|
||||||
authenticators = append(authenticators, oidcAuth)
|
authenticators = append(authenticators, oidcAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.KeystoneURL) > 0 {
|
|
||||||
keystoneAuth, err := newAuthenticatorFromKeystoneURL(config.KeystoneURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
authenticators = append(authenticators, keystoneAuth)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(config.WebhookTokenAuthnConfigFile) > 0 {
|
if len(config.WebhookTokenAuthnConfigFile) > 0 {
|
||||||
webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL)
|
webhookTokenAuth, err := newWebhookTokenAuthenticator(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnCacheTTL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -119,14 +120,21 @@ func New(config AuthenticatorConfig) (authenticator.Request, error) {
|
|||||||
authenticators = append(authenticators, webhookTokenAuth)
|
authenticators = append(authenticators, webhookTokenAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch len(authenticators) {
|
if len(authenticators) == 0 {
|
||||||
case 0:
|
if config.Anonymous {
|
||||||
|
return anonymous.NewAuthenticator(), nil
|
||||||
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
case 1:
|
|
||||||
return authenticators[0], nil
|
|
||||||
default:
|
|
||||||
return union.New(authenticators...), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authenticator := union.New(authenticators...)
|
||||||
|
|
||||||
|
if config.Anonymous {
|
||||||
|
// If the authenticator chain returns an error, return an error (don't consider a bad bearer token anonymous).
|
||||||
|
authenticator = union.NewFailOnError(authenticator, anonymous.NewAuthenticator())
|
||||||
|
}
|
||||||
|
|
||||||
|
return authenticator, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidServiceAccountKeyFile returns true if a valid public RSA key can be read from the given file
|
// IsValidServiceAccountKeyFile returns true if a valid public RSA key can be read from the given file
|
||||||
|
@ -71,6 +71,7 @@ type ServerRunOptions struct {
|
|||||||
AuthorizationWebhookCacheUnauthorizedTTL time.Duration
|
AuthorizationWebhookCacheUnauthorizedTTL time.Duration
|
||||||
AuthorizationRBACSuperUser string
|
AuthorizationRBACSuperUser string
|
||||||
|
|
||||||
|
AnonymousAuth bool
|
||||||
BasicAuthFile string
|
BasicAuthFile string
|
||||||
BindAddress net.IP
|
BindAddress net.IP
|
||||||
CertDirectory string
|
CertDirectory string
|
||||||
@ -127,6 +128,7 @@ func NewServerRunOptions() *ServerRunOptions {
|
|||||||
APIGroupPrefix: "/apis",
|
APIGroupPrefix: "/apis",
|
||||||
APIPrefix: "/api",
|
APIPrefix: "/api",
|
||||||
AdmissionControl: "AlwaysAdmit",
|
AdmissionControl: "AlwaysAdmit",
|
||||||
|
AnonymousAuth: true,
|
||||||
AuthorizationMode: "AlwaysAllow",
|
AuthorizationMode: "AlwaysAllow",
|
||||||
AuthorizationWebhookCacheAuthorizedTTL: 5 * time.Minute,
|
AuthorizationWebhookCacheAuthorizedTTL: 5 * time.Minute,
|
||||||
AuthorizationWebhookCacheUnauthorizedTTL: 30 * time.Second,
|
AuthorizationWebhookCacheUnauthorizedTTL: 30 * time.Second,
|
||||||
@ -269,6 +271,11 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
|
|||||||
"If specified, a username which avoids RBAC authorization checks and role binding "+
|
"If specified, a username which avoids RBAC authorization checks and role binding "+
|
||||||
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
|
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
|
||||||
|
|
||||||
|
fs.BoolVar(&s.AnonymousAuth, "anonymous-auth", s.AnonymousAuth, ""+
|
||||||
|
"Enables anonymous requests to the secure port of the API server. "+
|
||||||
|
"Requests that are not rejected by another authentication method are treated as anonymous requests. "+
|
||||||
|
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
|
||||||
|
|
||||||
fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, ""+
|
fs.StringVar(&s.BasicAuthFile, "basic-auth-file", s.BasicAuthFile, ""+
|
||||||
"If set, the file that will be used to admit requests to the secure port of the API server "+
|
"If set, the file that will be used to admit requests to the secure port of the API server "+
|
||||||
"via http basic authentication.")
|
"via http basic authentication.")
|
||||||
|
@ -35,12 +35,18 @@ type unionAuthRequestHandler struct {
|
|||||||
// New returns a request authenticator that validates credentials using a chain of authenticator.Request objects.
|
// New returns a request authenticator that validates credentials using a chain of authenticator.Request objects.
|
||||||
// The entire chain is tried until one succeeds. If all fail, an aggregate error is returned.
|
// The entire chain is tried until one succeeds. If all fail, an aggregate error is returned.
|
||||||
func New(authRequestHandlers ...authenticator.Request) authenticator.Request {
|
func New(authRequestHandlers ...authenticator.Request) authenticator.Request {
|
||||||
|
if len(authRequestHandlers) == 1 {
|
||||||
|
return authRequestHandlers[0]
|
||||||
|
}
|
||||||
return &unionAuthRequestHandler{Handlers: authRequestHandlers, FailOnError: false}
|
return &unionAuthRequestHandler{Handlers: authRequestHandlers, FailOnError: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFailOnError returns a request authenticator that validates credentials using a chain of authenticator.Request objects.
|
// NewFailOnError returns a request authenticator that validates credentials using a chain of authenticator.Request objects.
|
||||||
// The first error short-circuits the chain.
|
// The first error short-circuits the chain.
|
||||||
func NewFailOnError(authRequestHandlers ...authenticator.Request) authenticator.Request {
|
func NewFailOnError(authRequestHandlers ...authenticator.Request) authenticator.Request {
|
||||||
|
if len(authRequestHandlers) == 1 {
|
||||||
|
return authRequestHandlers[0]
|
||||||
|
}
|
||||||
return &unionAuthRequestHandler{Handlers: authRequestHandlers, FailOnError: true}
|
return &unionAuthRequestHandler{Handlers: authRequestHandlers, FailOnError: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user