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
|
apiAudiences = s.Authentication.ServiceAccounts.APIAudiences
|
||||||
maxExpiration = s.Authentication.ServiceAccounts.MaxExpiration
|
maxExpiration = s.Authentication.ServiceAccounts.MaxExpiration
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,12 +516,16 @@ func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController
|
||||||
rootCA = c.rootClientBuilder.ConfigOrDie("tokens-controller").CAData
|
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(
|
controller, err := serviceaccountcontroller.NewTokensController(
|
||||||
ctx.InformerFactory.Core().V1().ServiceAccounts(),
|
ctx.InformerFactory.Core().V1().ServiceAccounts(),
|
||||||
ctx.InformerFactory.Core().V1().Secrets(),
|
ctx.InformerFactory.Core().V1().Secrets(),
|
||||||
c.rootClientBuilder.ClientOrDie("tokens-controller"),
|
c.rootClientBuilder.ClientOrDie("tokens-controller"),
|
||||||
serviceaccountcontroller.TokensControllerOptions{
|
serviceaccountcontroller.TokensControllerOptions{
|
||||||
TokenGenerator: serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey),
|
TokenGenerator: tokenGenerator,
|
||||||
RootCA: rootCA,
|
RootCA: rootCA,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -54,25 +54,13 @@ type TokenGenerator interface {
|
||||||
// JWTTokenGenerator returns a TokenGenerator that generates signed JWT tokens, using the given privateKey.
|
// 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.
|
// privateKey is a PEM-encoded byte array of a private RSA key.
|
||||||
// JWTTokenAuthenticator()
|
// JWTTokenAuthenticator()
|
||||||
func JWTTokenGenerator(iss string, privateKey interface{}) TokenGenerator {
|
func JWTTokenGenerator(iss string, privateKey interface{}) (TokenGenerator, error) {
|
||||||
return &jwtTokenGenerator{
|
|
||||||
iss: iss,
|
|
||||||
privateKey: privateKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type jwtTokenGenerator struct {
|
|
||||||
iss string
|
|
||||||
privateKey interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims interface{}) (string, error) {
|
|
||||||
var alg jose.SignatureAlgorithm
|
var alg jose.SignatureAlgorithm
|
||||||
switch privateKey := j.privateKey.(type) {
|
switch pk := privateKey.(type) {
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
alg = jose.RS256
|
alg = jose.RS256
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
switch privateKey.Curve {
|
switch pk.Curve {
|
||||||
case elliptic.P256():
|
case elliptic.P256():
|
||||||
alg = jose.ES256
|
alg = jose.ES256
|
||||||
case elliptic.P384():
|
case elliptic.P384():
|
||||||
|
@ -80,25 +68,38 @@ func (j *jwtTokenGenerator) GenerateToken(claims *jwt.Claims, privateClaims inte
|
||||||
case elliptic.P521():
|
case elliptic.P521():
|
||||||
alg = jose.ES512
|
alg = jose.ES512
|
||||||
default:
|
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:
|
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(
|
signer, err := jose.NewSigner(
|
||||||
jose.SigningKey{
|
jose.SigningKey{
|
||||||
Algorithm: alg,
|
Algorithm: alg,
|
||||||
Key: j.privateKey,
|
Key: privateKey,
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
if err != 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
|
// claims are applied in reverse precedence
|
||||||
return jwt.Signed(signer).
|
return jwt.Signed(j.signer).
|
||||||
Claims(privateClaims).
|
Claims(privateClaims).
|
||||||
Claims(claims).
|
Claims(claims).
|
||||||
Claims(&jwt.Claims{
|
Claims(&jwt.Claims{
|
||||||
|
|
|
@ -127,7 +127,10 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the RSA token
|
// 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))
|
rsaToken, err := rsaGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *rsaSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error generating token: %v", err)
|
t.Fatalf("error generating token: %v", err)
|
||||||
|
@ -140,7 +143,10 @@ func TestTokenGenerateAndValidate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the ECDSA token
|
// 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))
|
ecdsaToken, err := ecdsaGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *ecdsaSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error generating token: %v", err)
|
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
|
// 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))
|
badIssuerToken, err := badIssuerGenerator.GenerateToken(serviceaccount.LegacyClaims(*serviceAccount, *rsaSecret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error generating token: %v", err)
|
t.Fatalf("error generating token: %v", err)
|
||||||
|
|
|
@ -81,7 +81,11 @@ func TestServiceAccountTokenCreate(t *testing.T) {
|
||||||
serviceaccount.NewValidator(aud, serviceaccountgetter.NewGetterFromClient(gcs)),
|
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.ServiceAccountAPIAudiences = aud
|
||||||
masterConfig.ExtraConfig.ServiceAccountMaxExpiration = maxExpirationDuration
|
masterConfig.ExtraConfig.ServiceAccountMaxExpiration = maxExpirationDuration
|
||||||
|
|
||||||
|
|
|
@ -436,11 +436,15 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie
|
||||||
apiServer.Close()
|
apiServer.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, serviceAccountKey)
|
||||||
|
if err != nil {
|
||||||
|
return rootClientset, clientConfig, stop, err
|
||||||
|
}
|
||||||
tokenController, err := serviceaccountcontroller.NewTokensController(
|
tokenController, err := serviceaccountcontroller.NewTokensController(
|
||||||
informers.Core().V1().ServiceAccounts(),
|
informers.Core().V1().ServiceAccounts(),
|
||||||
informers.Core().V1().Secrets(),
|
informers.Core().V1().Secrets(),
|
||||||
rootClientset,
|
rootClientset,
|
||||||
serviceaccountcontroller.TokensControllerOptions{TokenGenerator: serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, serviceAccountKey)},
|
serviceaccountcontroller.TokensControllerOptions{TokenGenerator: tokenGenerator},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rootClientset, clientConfig, stop, err
|
return rootClientset, clientConfig, stop, err
|
||||||
|
|
Loading…
Reference in New Issue