From 9242c1c22b0f4a865d46b90d861013038afdc9e4 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Tue, 25 Jul 2017 16:22:30 +0900 Subject: [PATCH] auth: a new option for configuring TTL of jwt tokens This commit adds a new option of --auth-token, ttl, for configuring TTL of jwt tokens. It can be specified like this: ``` --auth-token jwt,pub-key=,priv-key=,sign-method=,ttl=5m ``` In the above case, TTL will be 5 minutes. --- Documentation/op-guide/configuration.md | 4 ++-- auth/jwt.go | 28 ++++++++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Documentation/op-guide/configuration.md b/Documentation/op-guide/configuration.md index 8dadd3179171..ccaa857b8f94 100644 --- a/Documentation/op-guide/configuration.md +++ b/Documentation/op-guide/configuration.md @@ -298,8 +298,8 @@ Follow the instructions when using these flags. ## Auth flags ### --auth-token -+ Specify a token type and token specific options, especially for JWT. Its format is "type,var1=val1,var2=val2,...". Possible type is 'simple' or 'jwt'. Possible variables are 'sign-method' for specifying a sign method of jwt (its possible values are 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', or 'PS512'), 'pub-key' for specifying a path to a public key for verifying jwt, and 'priv-key' for specifying a path to a private key for signing jwt. -+ Example option of JWT: '--auth-token jwt,pub-key=app.rsa.pub,priv-key=app.rsa,sign-method=RS512' ++ Specify a token type and token specific options, especially for JWT. Its format is "type,var1=val1,var2=val2,...". Possible type is 'simple' or 'jwt'. Possible variables are 'sign-method' for specifying a sign method of jwt (its possible values are 'ES256', 'ES384', 'ES512', 'HS256', 'HS384', 'HS512', 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', or 'PS512'), 'pub-key' for specifying a path to a public key for verifying jwt, 'priv-key' for specifying a path to a private key for signing jwt, and 'ttl' for specifying TTL of jwt tokens. ++ Example option of JWT: '--auth-token jwt,pub-key=app.rsa.pub,priv-key=app.rsa,sign-method=RS512,ttl=10m' + default: "simple" [build-cluster]: clustering.md#static diff --git a/auth/jwt.go b/auth/jwt.go index 12ccc62c6995..4a722cf22443 100644 --- a/auth/jwt.go +++ b/auth/jwt.go @@ -17,6 +17,7 @@ package auth import ( "crypto/rsa" "io/ioutil" + "time" jwt "github.com/dgrijalva/jwt-go" "golang.org/x/net/context" @@ -26,6 +27,7 @@ type tokenJWT struct { signMethod string signKey *rsa.PrivateKey verifyKey *rsa.PublicKey + ttl time.Duration } func (t *tokenJWT) enable() {} @@ -52,7 +54,6 @@ func (t *tokenJWT) info(ctx context.Context, token string, rev uint64) (*AuthInf } claims := parsed.Claims.(jwt.MapClaims) - username = claims["username"].(string) revision = uint64(claims["revision"].(float64)) default: @@ -70,6 +71,7 @@ func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) jwt.MapClaims{ "username": username, "revision": revision, + "exp": time.Now().Add(t.ttl).Unix(), }) token, err := tk.SignedString(t.signKey) @@ -83,7 +85,7 @@ func (t *tokenJWT) assign(ctx context.Context, username string, revision uint64) return token, err } -func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath string, err error) { +func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath string, ttl time.Duration, err error) { for k, v := range opts { switch k { case "sign-method": @@ -92,24 +94,36 @@ func prepareOpts(opts map[string]string) (jwtSignMethod, jwtPubKeyPath, jwtPrivK jwtPubKeyPath = v case "priv-key": jwtPrivKeyPath = v + case "ttl": + ttl, err = time.ParseDuration(v) + if err != nil { + plog.Errorf("failed to parse ttl option (%s)", err) + return "", "", "", 0, ErrInvalidAuthOpts + } default: plog.Errorf("unknown token specific option: %s", k) - return "", "", "", ErrInvalidAuthOpts + return "", "", "", 0, ErrInvalidAuthOpts } } if len(jwtSignMethod) == 0 { - return "", "", "", ErrInvalidAuthOpts + return "", "", "", 0, ErrInvalidAuthOpts } - return jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, nil + return jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, ttl, nil } func newTokenProviderJWT(opts map[string]string) (*tokenJWT, error) { - jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, err := prepareOpts(opts) + jwtSignMethod, jwtPubKeyPath, jwtPrivKeyPath, ttl, err := prepareOpts(opts) if err != nil { return nil, ErrInvalidAuthOpts } - t := &tokenJWT{} + if ttl == 0 { + ttl = 5 * time.Minute + } + + t := &tokenJWT{ + ttl: ttl, + } t.signMethod = jwtSignMethod