Parcourir la source

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=<pub key path>,priv-key=<priv key path>,sign-method=<sign method>,ttl=5m
```

In the above case, TTL will be 5 minutes.
Hitoshi Mitake il y a 8 ans
Parent
commit
8fd01f56d6
2 fichiers modifiés avec 23 ajouts et 8 suppressions
  1. 2 2
      Documentation/op-guide/configuration.md
  2. 21 6
      auth/jwt.go

+ 2 - 2
Documentation/op-guide/configuration.md

@@ -361,8 +361,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"
 
 ## Experimental flags

+ 21 - 6
auth/jwt.go

@@ -18,6 +18,7 @@ import (
 	"context"
 	"crypto/rsa"
 	"io/ioutil"
+	"time"
 
 	jwt "github.com/dgrijalva/jwt-go"
 )
@@ -26,6 +27,7 @@ type tokenJWT struct {
 	signMethod string
 	signKey    *rsa.PrivateKey
 	verifyKey  *rsa.PublicKey
+	ttl        time.Duration
 }
 
 func (t *tokenJWT) enable()                         {}
@@ -70,6 +72,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 +86,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 +95,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