mirror of https://github.com/k3s-io/k3s
jwt: support opaque signer and push errors to token generator creation
parent
9ea39419eb
commit
e68f14a249
|
@ -360,7 +360,11 @@ func CreateKubeAPIServerConfig(
|
|||
}
|
||||
}
|
||||
|
||||
issuer = serviceaccount.JWTTokenGenerator(s.Authentication.ServiceAccounts.Issuer, sk)
|
||||
issuer, err = serviceaccount.JWTTokenGenerator(s.Authentication.ServiceAccounts.Issuer, sk)
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("failed to build token generator: %v", err)
|
||||
return
|
||||
}
|
||||
apiAudiences = s.Authentication.ServiceAccounts.APIAudiences
|
||||
maxExpiration = s.Authentication.ServiceAccounts.MaxExpiration
|
||||
}
|
||||
|
|
|
@ -516,12 +516,16 @@ func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController
|
|||
rootCA = c.rootClientBuilder.ConfigOrDie("tokens-controller").CAData
|
||||
}
|
||||
|
||||
tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to build token generator: %v", err)
|
||||
}
|
||||
controller, err := serviceaccountcontroller.NewTokensController(
|
||||
ctx.InformerFactory.Core().V1().ServiceAccounts(),
|
||||
ctx.InformerFactory.Core().V1().Secrets(),
|
||||
c.rootClientBuilder.ClientOrDie("tokens-controller"),
|
||||
serviceaccountcontroller.TokensControllerOptions{
|
||||
TokenGenerator: serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey),
|
||||
TokenGenerator: tokenGenerator,
|
||||
RootCA: rootCA,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -54,25 +54,13 @@ type TokenGenerator interface {
|
|||
// JWTTokenGenerator returns a TokenGenerator that generates signed JWT tokens, using the given privateKey.
|
||||
// privateKey is a PEM-encoded byte array of a private RSA key.
|
||||
// JWTTokenAuthenticator()
|
||||
func JWTTokenGenerator(iss string, privateKey interface{}) TokenGenerator {
|
||||
return &jwtTokenGenerator{
|
||||
iss: iss,
|
||||
privateKey: privateKey,
|
||||
}
|
||||
}
|
||||
|
||||
type jwtTokenGenerator struct {
|
||||
iss string
|
||||
privateKey interface{}
|
||||
}
|
||||
|
||||
func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error) {
|
||||
func JWTTokenGenerator(iss string, privateKey interface{}) (TokenGenerator, error) {
|
||||
var alg jose.SignatureAlgorithm
|
||||
switch privateKey := j.privateKey.(type) {
|
||||
switch pk := privateKey.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
alg = jose.RS256
|
||||
case *ecdsa.PrivateKey:
|
||||
switch privateKey.Curve {
|
||||
switch pk.Curve {
|
||||
case elliptic.P256():
|
||||
alg = jose.ES256
|
||||
case elliptic.P384():
|
||||
|
@ -80,25 +68,38 @@ func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims inte
|
|||
case elliptic.P521():
|
||||
alg = jose.ES512
|
||||
default:
|
||||
return "", fmt.Errorf("unknown private key curve, must be 256, 384, or 521")
|
||||
return nil, fmt.Errorf("unknown private key curve, must be 256, 384, or 521")
|
||||
}
|
||||
case jose.OpaqueSigner:
|
||||
alg = jose.SignatureAlgorithm(pk.Public().Algorithm)
|
||||
default:
|
||||
return "", fmt.Errorf("unknown private key type %T, must be *rsa.PrivateKey or *ecdsa.PrivateKey", j.privateKey)
|
||||
return nil, fmt.Errorf("unknown private key type %T, must be *rsa.PrivateKey, *ecdsa.PrivateKey, or jose.OpaqueSigner", privateKey)
|
||||
}
|
||||
|
||||
signer, err := jose.NewSigner(
|
||||
jose.SigningKey{
|
||||
Algorithm: alg,
|
||||
Key: j.privateKey,
|
||||
Key: privateKey,
|
||||
},
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
return &jwtTokenGenerator{
|
||||
iss: iss,
|
||||
signer: signer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type jwtTokenGenerator struct {
|
||||
iss string
|
||||
signer jose.Signer
|
||||
}
|
||||
|
||||
func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error) {
|
||||
// claims are applied in reverse precedence
|
||||
return jwt.Signed(signer).
|
||||
return jwt.Signed(j.signer).
|
||||
Claims(privateClaims).
|
||||
Claims(claims).
|
||||
Claims(&jwt.Claims{
|
||||
|
|
|
@ -127,7 +127,10 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
// Generate the RSA token
|
||||
rsaGenerator := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, getPrivateKey(rsaPrivateKey))
|
||||
rsaGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, getPrivateKey(rsaPrivateKey))
|
||||
if err != nil {
|
||||
t.Fatalf("error making generator: %v", err)
|
||||
}
|
||||
rsaToken, err := rsaGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *rsaSecret))
|
||||
if err != nil {
|
||||
t.Fatalf("error generating token: %v", err)
|
||||
|
@ -140,7 +143,10 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
// Generate the ECDSA token
|
||||
ecdsaGenerator := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, getPrivateKey(ecdsaPrivateKey))
|
||||
ecdsaGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, getPrivateKey(ecdsaPrivateKey))
|
||||
if err != nil {
|
||||
t.Fatalf("error making generator: %v", err)
|
||||
}
|
||||
ecdsaToken, err := ecdsaGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *ecdsaSecret))
|
||||
if err != nil {
|
||||
t.Fatalf("error generating token: %v", err)
|
||||
|
@ -153,7 +159,10 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
// Generate signer with same keys as RSA signer but different issuer
|
||||
badIssuerGenerator := serviceaccount.JWTTokenGenerator("foo", getPrivateKey(rsaPrivateKey))
|
||||
badIssuerGenerator, err := serviceaccount.JWTTokenGenerator("foo", getPrivateKey(rsaPrivateKey))
|
||||
if err != nil {
|
||||
t.Fatalf("error making generator: %v", err)
|
||||
}
|
||||
badIssuerToken, err := badIssuerGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *rsaSecret))
|
||||
if err != nil {
|
||||
t.Fatalf("error generating token: %v", err)
|
||||
|
|
|
@ -81,7 +81,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
|||
serviceaccount.NewValidator(aud, serviceaccountgetter.NewGetterFromClient(gcs)),
|
||||
),
|
||||
)
|
||||
masterConfig.ExtraConfig.ServiceAccountIssuer = serviceaccount.JWTTokenGenerator(iss, sk)
|
||||
tokenGenerator, err := serviceaccount.JWTTokenGenerator(iss, sk)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
masterConfig.ExtraConfig.ServiceAccountIssuer = tokenGenerator
|
||||
masterConfig.ExtraConfig.ServiceAccountAPIAudiences = aud
|
||||
masterConfig.ExtraConfig.ServiceAccountMaxExpiration = maxExpirationDuration
|
||||
|
||||
|
|
|
@ -436,11 +436,15 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
|
|||
apiServer.Close()
|
||||
}
|
||||
|
||||
tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, serviceAccountKey)
|
||||
if err != nil {
|
||||
return rootClientset, clientConfig, stop, err
|
||||
}
|
||||
tokenController, err := serviceaccountcontroller.NewTokensController(
|
||||
informers.Core().V1().ServiceAccounts(),
|
||||
informers.Core().V1().Secrets(),
|
||||
rootClientset,
|
||||
serviceaccountcontroller.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, serviceAccountKey)},
|
||||
serviceaccountcontroller.TokensControllerOptions{TokenGenerator: tokenGenerator},
|
||||
)
|
||||
if err != nil {
|
||||
return rootClientset, clientConfig, stop, err
|
||||
|
|
Loading…
Reference in New Issue