mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-14 06:15:45 +00:00
Support all key algs with structured authn config
Signed-off-by: Monis Khan <mok@microsoft.com>
This commit is contained in:
parent
b8a59346fe
commit
b5e0068325
@ -40,6 +40,7 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/server/egressselector"
|
"k8s.io/apiserver/pkg/server/egressselector"
|
||||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/apiserver/plugin/pkg/authenticator/token/oidc"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
v1listers "k8s.io/client-go/listers/core/v1"
|
v1listers "k8s.io/client-go/listers/core/v1"
|
||||||
@ -461,6 +462,9 @@ func (o *BuiltInAuthenticationOptions) ToAuthenticationConfig() (kubeauthenticat
|
|||||||
if ret.AuthenticationConfig, err = loadAuthenticationConfig(o.AuthenticationConfigFile); err != nil {
|
if ret.AuthenticationConfig, err = loadAuthenticationConfig(o.AuthenticationConfigFile); err != nil {
|
||||||
return kubeauthenticator.Config{}, err
|
return kubeauthenticator.Config{}, err
|
||||||
}
|
}
|
||||||
|
// all known signing algs are allowed when using authentication config
|
||||||
|
// TODO: what we really want to express is 'any alg is fine as long it matches a public key'
|
||||||
|
ret.OIDCSigningAlgs = oidc.AllValidSigningAlgorithms()
|
||||||
} else if o.OIDC != nil && len(o.OIDC.IssuerURL) > 0 && len(o.OIDC.ClientID) > 0 {
|
} else if o.OIDC != nil && len(o.OIDC.IssuerURL) > 0 && len(o.OIDC.ClientID) > 0 {
|
||||||
usernamePrefix := o.OIDC.UsernamePrefix
|
usernamePrefix := o.OIDC.UsernamePrefix
|
||||||
|
|
||||||
|
@ -446,6 +446,8 @@ func TestBuiltInAuthenticationOptionsAddFlags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestToAuthenticationConfig_OIDC(t *testing.T) {
|
func TestToAuthenticationConfig_OIDC(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.StructuredAuthenticationConfiguration, true)()
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args []string
|
args []string
|
||||||
@ -640,6 +642,43 @@ func TestToAuthenticationConfig_OIDC(t *testing.T) {
|
|||||||
OIDCSigningAlgs: []string{"RS256"},
|
OIDCSigningAlgs: []string{"RS256"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "basic authentication configuration",
|
||||||
|
args: []string{
|
||||||
|
"--authentication-config=" + writeTempFile(t, `
|
||||||
|
apiVersion: apiserver.config.k8s.io/v1alpha1
|
||||||
|
kind: AuthenticationConfiguration
|
||||||
|
jwt:
|
||||||
|
- issuer:
|
||||||
|
url: https://test-issuer
|
||||||
|
audiences: [ "🐼" ]
|
||||||
|
claimMappings:
|
||||||
|
username:
|
||||||
|
claim: sub
|
||||||
|
prefix: ""
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectConfig: kubeauthenticator.Config{
|
||||||
|
TokenSuccessCacheTTL: 10 * time.Second,
|
||||||
|
AuthenticationConfig: &apiserver.AuthenticationConfiguration{
|
||||||
|
JWT: []apiserver.JWTAuthenticator{
|
||||||
|
{
|
||||||
|
Issuer: apiserver.Issuer{
|
||||||
|
URL: "https://test-issuer",
|
||||||
|
Audiences: []string{"🐼"},
|
||||||
|
},
|
||||||
|
ClaimMappings: apiserver.ClaimMappings{
|
||||||
|
Username: apiserver.PrefixedClaimOrExpression{
|
||||||
|
Claim: "sub",
|
||||||
|
Prefix: pointer.String(""),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OIDCSigningAlgs: []string{"ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "RS256", "RS384", "RS512"},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testcase := range testCases {
|
for _, testcase := range testCases {
|
||||||
|
@ -49,6 +49,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/net"
|
"k8s.io/apimachinery/pkg/util/net"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
"k8s.io/apiserver/pkg/apis/apiserver"
|
"k8s.io/apiserver/pkg/apis/apiserver"
|
||||||
apiservervalidation "k8s.io/apiserver/pkg/apis/apiserver/validation"
|
apiservervalidation "k8s.io/apiserver/pkg/apis/apiserver/validation"
|
||||||
@ -196,8 +197,11 @@ func (a *Authenticator) Close() {
|
|||||||
a.cancel()
|
a.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// whitelist of signing algorithms to ensure users don't mistakenly pass something
|
func AllValidSigningAlgorithms() []string {
|
||||||
// goofy.
|
return sets.List(sets.KeySet(allowedSigningAlgs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// allowlist of signing algorithms to ensure users don't mistakenly pass something goofy.
|
||||||
var allowedSigningAlgs = map[string]bool{
|
var allowedSigningAlgs = map[string]bool{
|
||||||
oidc.RS256: true,
|
oidc.RS256: true,
|
||||||
oidc.RS384: true,
|
oidc.RS384: true,
|
||||||
|
@ -18,6 +18,8 @@ package oidc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
@ -280,6 +282,34 @@ jwt:
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, singleTestRunner(useAuthenticationConfig, rsaGenerateKey, tt))
|
t.Run(tt.name, singleTestRunner(useAuthenticationConfig, rsaGenerateKey, tt))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, tt := range []singleTest[*ecdsa.PrivateKey, *ecdsa.PublicKey]{
|
||||||
|
{
|
||||||
|
name: "ID token is ok",
|
||||||
|
configureInfrastructure: configureTestInfrastructure[*ecdsa.PrivateKey, *ecdsa.PublicKey],
|
||||||
|
configureOIDCServerBehaviour: func(t *testing.T, oidcServer *utilsoidc.TestServer, signingPrivateKey *ecdsa.PrivateKey) {
|
||||||
|
idTokenLifetime := time.Second * 1200
|
||||||
|
oidcServer.TokenHandler().EXPECT().Token().Times(1).DoAndReturn(utilsoidc.TokenHandlerBehaviorReturningPredefinedJWT(
|
||||||
|
t,
|
||||||
|
signingPrivateKey,
|
||||||
|
map[string]interface{}{
|
||||||
|
"iss": oidcServer.URL(),
|
||||||
|
"sub": defaultOIDCClaimedUsername,
|
||||||
|
"aud": defaultOIDCClientID,
|
||||||
|
"exp": time.Now().Add(idTokenLifetime).Unix(),
|
||||||
|
},
|
||||||
|
defaultStubAccessToken,
|
||||||
|
defaultStubRefreshToken,
|
||||||
|
))
|
||||||
|
},
|
||||||
|
configureClient: configureClientFetchingOIDCCredentials,
|
||||||
|
assertErrFn: func(t *testing.T, errorToCheck error) {
|
||||||
|
assert.NoError(t, errorToCheck)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tt.name, singleTestRunner(useAuthenticationConfig, ecdsaGenerateKey, tt))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type singleTest[K utilsoidc.JosePrivateKey, L utilsoidc.JosePublicKey] struct {
|
type singleTest[K utilsoidc.JosePrivateKey, L utilsoidc.JosePublicKey] struct {
|
||||||
@ -755,6 +785,15 @@ func rsaGenerateKey(t *testing.T) (*rsa.PrivateKey, *rsa.PublicKey) {
|
|||||||
return privateKey, &privateKey.PublicKey
|
return privateKey, &privateKey.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ecdsaGenerateKey(t *testing.T) (*ecdsa.PrivateKey, *ecdsa.PublicKey) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return privateKey, &privateKey.PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
func configureTestInfrastructure[K utilsoidc.JosePrivateKey, L utilsoidc.JosePublicKey](t *testing.T, fn authenticationConfigFunc, keyFunc func(t *testing.T) (K, L)) (
|
func configureTestInfrastructure[K utilsoidc.JosePrivateKey, L utilsoidc.JosePublicKey](t *testing.T, fn authenticationConfigFunc, keyFunc func(t *testing.T) (K, L)) (
|
||||||
oidcServer *utilsoidc.TestServer,
|
oidcServer *utilsoidc.TestServer,
|
||||||
apiServer *kubeapiserverapptesting.TestServer,
|
apiServer *kubeapiserverapptesting.TestServer,
|
||||||
|
Loading…
Reference in New Issue
Block a user