add the ability for dynamic header names in delegated authentication
Kubernetes-commit: 58256346693717fd12f121f0cf74fe1e003edb0f
This commit is contained in:
parent
934c73955b
commit
703545a3db
|
@ -63,16 +63,13 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur
|
||||||
// front-proxy first, then remote
|
// front-proxy first, then remote
|
||||||
// Add the front proxy authenticator if requested
|
// Add the front proxy authenticator if requested
|
||||||
if c.RequestHeaderConfig != nil {
|
if c.RequestHeaderConfig != nil {
|
||||||
requestHeaderAuthenticator, err := headerrequest.NewDynamicVerifyOptionsSecure(
|
requestHeaderAuthenticator := headerrequest.NewDynamicVerifyOptionsSecure(
|
||||||
c.RequestHeaderConfig.VerifyOptionFn,
|
c.RequestHeaderConfig.VerifyOptionFn,
|
||||||
c.RequestHeaderConfig.AllowedClientNames,
|
c.RequestHeaderConfig.AllowedClientNames,
|
||||||
c.RequestHeaderConfig.UsernameHeaders,
|
c.RequestHeaderConfig.UsernameHeaders,
|
||||||
c.RequestHeaderConfig.GroupHeaders,
|
c.RequestHeaderConfig.GroupHeaders,
|
||||||
c.RequestHeaderConfig.ExtraHeaderPrefixes,
|
c.RequestHeaderConfig.ExtraHeaderPrefixes,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
authenticators = append(authenticators, requestHeaderAuthenticator)
|
authenticators = append(authenticators, requestHeaderAuthenticator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,21 @@ limitations under the License.
|
||||||
package authenticatorfactory
|
package authenticatorfactory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||||
x509request "k8s.io/apiserver/pkg/authentication/request/x509"
|
x509request "k8s.io/apiserver/pkg/authentication/request/x509"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RequestHeaderConfig struct {
|
type RequestHeaderConfig struct {
|
||||||
// UsernameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
|
// UsernameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
|
||||||
UsernameHeaders []string
|
UsernameHeaders headerrequest.StringSliceProvider
|
||||||
// GroupHeaders are the headers to check (case-insensitively) for a group names. All values will be used.
|
// GroupHeaders are the headers to check (case-insensitively) for a group names. All values will be used.
|
||||||
GroupHeaders []string
|
GroupHeaders headerrequest.StringSliceProvider
|
||||||
// ExtraHeaderPrefixes are the head prefixes to check (case-insentively) for filling in
|
// ExtraHeaderPrefixes are the head prefixes to check (case-insentively) for filling in
|
||||||
// the user.Info.Extra. All values of all matching headers will be added.
|
// the user.Info.Extra. All values of all matching headers will be added.
|
||||||
ExtraHeaderPrefixes []string
|
ExtraHeaderPrefixes headerrequest.StringSliceProvider
|
||||||
// VerifyOptionFn are the options for verifying incoming connections using mTLS. Generally this points to CA bundle file which is used verify the identity of the front proxy.
|
// VerifyOptionFn are the options for verifying incoming connections using mTLS. Generally this points to CA bundle file which is used verify the identity of the front proxy.
|
||||||
// It may produce different options at will.
|
// It may produce different options at will.
|
||||||
VerifyOptionFn x509request.VerifyOptionFunc
|
VerifyOptionFn x509request.VerifyOptionFunc
|
||||||
// AllowedClientNames is a list of common names that may be presented by the authenticating front proxy. Empty means: accept any.
|
// AllowedClientNames is a list of common names that may be presented by the authenticating front proxy. Empty means: accept any.
|
||||||
AllowedClientNames []string
|
AllowedClientNames headerrequest.StringSliceProvider
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,26 +24,47 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
x509request "k8s.io/apiserver/pkg/authentication/request/x509"
|
x509request "k8s.io/apiserver/pkg/authentication/request/x509"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
utilcert "k8s.io/client-go/util/cert"
|
utilcert "k8s.io/client-go/util/cert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// StringSliceProvider is a way to get a string slice value. It is heavily used for authentication headers among other places.
|
||||||
|
type StringSliceProvider interface {
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
Value() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceProviderFunc is a function that matches the StringSliceProvider interface
|
||||||
|
type StringSliceProviderFunc func() []string
|
||||||
|
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
func (d StringSliceProviderFunc) Value() []string {
|
||||||
|
return d()
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticStringSlice a StringSliceProvider that returns a fixed value
|
||||||
|
type StaticStringSlice []string
|
||||||
|
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
func (s StaticStringSlice) Value() []string {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
type requestHeaderAuthRequestHandler struct {
|
type requestHeaderAuthRequestHandler struct {
|
||||||
// nameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
|
// nameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
|
||||||
nameHeaders []string
|
nameHeaders StringSliceProvider
|
||||||
|
|
||||||
// groupHeaders are the headers to check (case-insensitively) for group membership. All values of all headers will be added.
|
// groupHeaders are the headers to check (case-insensitively) for group membership. All values of all headers will be added.
|
||||||
groupHeaders []string
|
groupHeaders StringSliceProvider
|
||||||
|
|
||||||
// extraHeaderPrefixes are the head prefixes to check (case-insensitively) for filling in
|
// extraHeaderPrefixes are the head prefixes to check (case-insensitively) for filling in
|
||||||
// the user.Info.Extra. All values of all matching headers will be added.
|
// the user.Info.Extra. All values of all matching headers will be added.
|
||||||
extraHeaderPrefixes []string
|
extraHeaderPrefixes StringSliceProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(nameHeaders []string, groupHeaders []string, extraHeaderPrefixes []string) (authenticator.Request, error) {
|
func New(nameHeaders, groupHeaders, extraHeaderPrefixes []string) (authenticator.Request, error) {
|
||||||
trimmedNameHeaders, err := trimHeaders(nameHeaders...)
|
trimmedNameHeaders, err := trimHeaders(nameHeaders...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -57,11 +78,19 @@ func New(nameHeaders []string, groupHeaders []string, extraHeaderPrefixes []stri
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NewDynamic(
|
||||||
|
StaticStringSlice(trimmedNameHeaders),
|
||||||
|
StaticStringSlice(trimmedGroupHeaders),
|
||||||
|
StaticStringSlice(trimmedExtraHeaderPrefixes),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDynamic(nameHeaders, groupHeaders, extraHeaderPrefixes StringSliceProvider) authenticator.Request {
|
||||||
return &requestHeaderAuthRequestHandler{
|
return &requestHeaderAuthRequestHandler{
|
||||||
nameHeaders: trimmedNameHeaders,
|
nameHeaders: nameHeaders,
|
||||||
groupHeaders: trimmedGroupHeaders,
|
groupHeaders: groupHeaders,
|
||||||
extraHeaderPrefixes: trimmedExtraHeaderPrefixes,
|
extraHeaderPrefixes: extraHeaderPrefixes,
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimHeaders(headerNames ...string) ([]string, error) {
|
func trimHeaders(headerNames ...string) ([]string, error) {
|
||||||
|
@ -97,36 +126,51 @@ func NewSecure(clientCA string, proxyClientNames []string, nameHeaders []string,
|
||||||
opts.Roots.AddCert(cert)
|
opts.Roots.AddCert(cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewDynamicVerifyOptionsSecure(x509request.StaticVerifierFn(opts), proxyClientNames, nameHeaders, groupHeaders, extraHeaderPrefixes)
|
trimmedNameHeaders, err := trimHeaders(nameHeaders...)
|
||||||
}
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
// TODO make the string slices dynamic too.
|
}
|
||||||
func NewDynamicVerifyOptionsSecure(verifyOptionFn x509request.VerifyOptionFunc, proxyClientNames []string, nameHeaders []string, groupHeaders []string, extraHeaderPrefixes []string) (authenticator.Request, error) {
|
trimmedGroupHeaders, err := trimHeaders(groupHeaders...)
|
||||||
headerAuthenticator, err := New(nameHeaders, groupHeaders, extraHeaderPrefixes)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
trimmedExtraHeaderPrefixes, err := trimHeaders(extraHeaderPrefixes...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return x509request.NewDynamicCAVerifier(verifyOptionFn, headerAuthenticator, sets.NewString(proxyClientNames...)), nil
|
return NewDynamicVerifyOptionsSecure(
|
||||||
|
x509request.StaticVerifierFn(opts),
|
||||||
|
StaticStringSlice(proxyClientNames),
|
||||||
|
StaticStringSlice(trimmedNameHeaders),
|
||||||
|
StaticStringSlice(trimmedGroupHeaders),
|
||||||
|
StaticStringSlice(trimmedExtraHeaderPrefixes),
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDynamicVerifyOptionsSecure(verifyOptionFn x509request.VerifyOptionFunc, proxyClientNames, nameHeaders, groupHeaders, extraHeaderPrefixes StringSliceProvider) authenticator.Request {
|
||||||
|
headerAuthenticator := NewDynamic(nameHeaders, groupHeaders, extraHeaderPrefixes)
|
||||||
|
|
||||||
|
return x509request.NewDynamicCAVerifier(verifyOptionFn, headerAuthenticator, proxyClientNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *requestHeaderAuthRequestHandler) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {
|
func (a *requestHeaderAuthRequestHandler) AuthenticateRequest(req *http.Request) (*authenticator.Response, bool, error) {
|
||||||
name := headerValue(req.Header, a.nameHeaders)
|
name := headerValue(req.Header, a.nameHeaders.Value())
|
||||||
if len(name) == 0 {
|
if len(name) == 0 {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
groups := allHeaderValues(req.Header, a.groupHeaders)
|
groups := allHeaderValues(req.Header, a.groupHeaders.Value())
|
||||||
extra := newExtra(req.Header, a.extraHeaderPrefixes)
|
extra := newExtra(req.Header, a.extraHeaderPrefixes.Value())
|
||||||
|
|
||||||
// clear headers used for authentication
|
// clear headers used for authentication
|
||||||
for _, headerName := range a.nameHeaders {
|
for _, headerName := range a.nameHeaders.Value() {
|
||||||
req.Header.Del(headerName)
|
req.Header.Del(headerName)
|
||||||
}
|
}
|
||||||
for _, headerName := range a.groupHeaders {
|
for _, headerName := range a.groupHeaders.Value() {
|
||||||
req.Header.Del(headerName)
|
req.Header.Del(headerName)
|
||||||
}
|
}
|
||||||
for k := range extra {
|
for k := range extra {
|
||||||
for _, prefix := range a.extraHeaderPrefixes {
|
for _, prefix := range a.extraHeaderPrefixes.Value() {
|
||||||
req.Header.Del(prefix + k)
|
req.Header.Del(prefix + k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,3 +47,25 @@ func NewStaticVerifierFromFile(clientCA string) (VerifyOptionFunc, error) {
|
||||||
|
|
||||||
return StaticVerifierFn(opts), nil
|
return StaticVerifierFn(opts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringSliceProvider is a way to get a string slice value. It is heavily used for authentication headers among other places.
|
||||||
|
type StringSliceProvider interface {
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
Value() []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceProviderFunc is a function that matches the StringSliceProvider interface
|
||||||
|
type StringSliceProviderFunc func() []string
|
||||||
|
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
func (d StringSliceProviderFunc) Value() []string {
|
||||||
|
return d()
|
||||||
|
}
|
||||||
|
|
||||||
|
// StaticStringSlice a StringSliceProvider that returns a fixed value
|
||||||
|
type StaticStringSlice []string
|
||||||
|
|
||||||
|
// Value returns the current string slice. Callers should never mutate the returned value.
|
||||||
|
func (s StaticStringSlice) Value() []string {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
|
@ -148,17 +148,17 @@ type Verifier struct {
|
||||||
|
|
||||||
// allowedCommonNames contains the common names which a verified certificate is allowed to have.
|
// allowedCommonNames contains the common names which a verified certificate is allowed to have.
|
||||||
// If empty, all verified certificates are allowed.
|
// If empty, all verified certificates are allowed.
|
||||||
allowedCommonNames sets.String
|
allowedCommonNames StringSliceProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewVerifier create a request.Authenticator by verifying a client cert on the request, then delegating to the wrapped auth
|
// NewVerifier create a request.Authenticator by verifying a client cert on the request, then delegating to the wrapped auth
|
||||||
func NewVerifier(opts x509.VerifyOptions, auth authenticator.Request, allowedCommonNames sets.String) authenticator.Request {
|
func NewVerifier(opts x509.VerifyOptions, auth authenticator.Request, allowedCommonNames sets.String) authenticator.Request {
|
||||||
return NewDynamicCAVerifier(StaticVerifierFn(opts), auth, allowedCommonNames)
|
return NewDynamicCAVerifier(StaticVerifierFn(opts), auth, StaticStringSlice(allowedCommonNames.List()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDynamicCAVerifier create a request.Authenticator by verifying a client cert on the request, then delegating to the wrapped auth
|
// NewDynamicCAVerifier create a request.Authenticator by verifying a client cert on the request, then delegating to the wrapped auth
|
||||||
// TODO make the allowedCommonNames dynamic
|
// TODO make the allowedCommonNames dynamic
|
||||||
func NewDynamicCAVerifier(verifyOptionsFn VerifyOptionFunc, auth authenticator.Request, allowedCommonNames sets.String) authenticator.Request {
|
func NewDynamicCAVerifier(verifyOptionsFn VerifyOptionFunc, auth authenticator.Request, allowedCommonNames StringSliceProvider) authenticator.Request {
|
||||||
return &Verifier{verifyOptionsFn, auth, allowedCommonNames}
|
return &Verifier{verifyOptionsFn, auth, allowedCommonNames}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,12 +188,14 @@ func (a *Verifier) AuthenticateRequest(req *http.Request) (*authenticator.Respon
|
||||||
|
|
||||||
func (a *Verifier) verifySubject(subject pkix.Name) error {
|
func (a *Verifier) verifySubject(subject pkix.Name) error {
|
||||||
// No CN restrictions
|
// No CN restrictions
|
||||||
if len(a.allowedCommonNames) == 0 {
|
if len(a.allowedCommonNames.Value()) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Enforce CN restrictions
|
// Enforce CN restrictions
|
||||||
if a.allowedCommonNames.Has(subject.CommonName) {
|
for _, allowedCommonName := range a.allowedCommonNames.Value() {
|
||||||
return nil
|
if allowedCommonName == subject.CommonName {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fmt.Errorf("x509: subject with cn=%s is not in the allowed list", subject.CommonName)
|
return fmt.Errorf("x509: subject with cn=%s is not in the allowed list", subject.CommonName)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
@ -28,6 +29,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
|
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||||
"k8s.io/apiserver/pkg/authentication/request/x509"
|
"k8s.io/apiserver/pkg/authentication/request/x509"
|
||||||
"k8s.io/apiserver/pkg/server"
|
"k8s.io/apiserver/pkg/server"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
|
@ -49,6 +51,35 @@ type RequestHeaderAuthenticationOptions struct {
|
||||||
AllowedNames []string
|
AllowedNames []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *RequestHeaderAuthenticationOptions) Validate() []error {
|
||||||
|
allErrors := []error{}
|
||||||
|
|
||||||
|
if err := checkForWhiteSpaceOnly("requestheader-username-headers", s.UsernameHeaders...); err != nil {
|
||||||
|
allErrors = append(allErrors, err)
|
||||||
|
}
|
||||||
|
if err := checkForWhiteSpaceOnly("requestheader-group-headers", s.GroupHeaders...); err != nil {
|
||||||
|
allErrors = append(allErrors, err)
|
||||||
|
}
|
||||||
|
if err := checkForWhiteSpaceOnly("requestheader-extra-headers-prefix", s.ExtraHeaderPrefixes...); err != nil {
|
||||||
|
allErrors = append(allErrors, err)
|
||||||
|
}
|
||||||
|
if err := checkForWhiteSpaceOnly("requestheader-allowed-names", s.AllowedNames...); err != nil {
|
||||||
|
allErrors = append(allErrors, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return allErrors
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkForWhiteSpaceOnly(flag string, headerNames ...string) error {
|
||||||
|
for _, headerName := range headerNames {
|
||||||
|
if len(strings.TrimSpace(headerName)) == 0 {
|
||||||
|
return fmt.Errorf("empty value in %q", flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *RequestHeaderAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
func (s *RequestHeaderAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return
|
return
|
||||||
|
@ -87,11 +118,11 @@ func (s *RequestHeaderAuthenticationOptions) ToAuthenticationRequestHeaderConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
return &authenticatorfactory.RequestHeaderConfig{
|
return &authenticatorfactory.RequestHeaderConfig{
|
||||||
UsernameHeaders: s.UsernameHeaders,
|
UsernameHeaders: headerrequest.StaticStringSlice(s.UsernameHeaders),
|
||||||
GroupHeaders: s.GroupHeaders,
|
GroupHeaders: headerrequest.StaticStringSlice(s.GroupHeaders),
|
||||||
ExtraHeaderPrefixes: s.ExtraHeaderPrefixes,
|
ExtraHeaderPrefixes: headerrequest.StaticStringSlice(s.ExtraHeaderPrefixes),
|
||||||
VerifyOptionFn: verifyFn,
|
VerifyOptionFn: verifyFn,
|
||||||
AllowedClientNames: s.AllowedNames,
|
AllowedClientNames: headerrequest.StaticStringSlice(s.AllowedNames),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +198,8 @@ func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions {
|
||||||
|
|
||||||
func (s *DelegatingAuthenticationOptions) Validate() []error {
|
func (s *DelegatingAuthenticationOptions) Validate() []error {
|
||||||
allErrors := []error{}
|
allErrors := []error{}
|
||||||
|
allErrors = append(allErrors, s.RequestHeader.Validate()...)
|
||||||
|
|
||||||
return allErrors
|
return allErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
|
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
|
||||||
"k8s.io/apiserver/pkg/server"
|
"k8s.io/apiserver/pkg/server"
|
||||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||||
)
|
)
|
||||||
|
@ -37,27 +38,27 @@ func TestToAuthenticationRequestHeaderConfig(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "test when ClientCAFile is nil",
|
name: "test when ClientCAFile is nil",
|
||||||
testOptions: &RequestHeaderAuthenticationOptions{
|
testOptions: &RequestHeaderAuthenticationOptions{
|
||||||
UsernameHeaders: []string{"x-remote-user"},
|
UsernameHeaders: headerrequest.StaticStringSlice{"x-remote-user"},
|
||||||
GroupHeaders: []string{"x-remote-group"},
|
GroupHeaders: headerrequest.StaticStringSlice{"x-remote-group"},
|
||||||
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
ExtraHeaderPrefixes: headerrequest.StaticStringSlice{"x-remote-extra-"},
|
||||||
AllowedNames: []string{"kube-aggregator"},
|
AllowedNames: headerrequest.StaticStringSlice{"kube-aggregator"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test when ClientCAFile is not nil",
|
name: "test when ClientCAFile is not nil",
|
||||||
testOptions: &RequestHeaderAuthenticationOptions{
|
testOptions: &RequestHeaderAuthenticationOptions{
|
||||||
ClientCAFile: "testdata/root.pem",
|
ClientCAFile: "testdata/root.pem",
|
||||||
UsernameHeaders: []string{"x-remote-user"},
|
UsernameHeaders: headerrequest.StaticStringSlice{"x-remote-user"},
|
||||||
GroupHeaders: []string{"x-remote-group"},
|
GroupHeaders: headerrequest.StaticStringSlice{"x-remote-group"},
|
||||||
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
ExtraHeaderPrefixes: headerrequest.StaticStringSlice{"x-remote-extra-"},
|
||||||
AllowedNames: []string{"kube-aggregator"},
|
AllowedNames: headerrequest.StaticStringSlice{"kube-aggregator"},
|
||||||
},
|
},
|
||||||
expectConfig: &authenticatorfactory.RequestHeaderConfig{
|
expectConfig: &authenticatorfactory.RequestHeaderConfig{
|
||||||
UsernameHeaders: []string{"x-remote-user"},
|
UsernameHeaders: headerrequest.StaticStringSlice{"x-remote-user"},
|
||||||
GroupHeaders: []string{"x-remote-group"},
|
GroupHeaders: headerrequest.StaticStringSlice{"x-remote-group"},
|
||||||
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
|
ExtraHeaderPrefixes: headerrequest.StaticStringSlice{"x-remote-extra-"},
|
||||||
VerifyOptionFn: nil, // this is nil because you can't compare functions
|
VerifyOptionFn: nil, // this is nil because you can't compare functions
|
||||||
AllowedClientNames: []string{"kube-aggregator"},
|
AllowedClientNames: headerrequest.StaticStringSlice{"kube-aggregator"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue