diff --git a/README b/README index 17f0299..4bc1a4f 100644 --- a/README +++ b/README @@ -319,8 +319,9 @@ specify either an authorisation server or an authorisation portal. "authServer": "https://auth.example.org", } -If multiple keys are provided, then they will all be tried in turn (the -kid field, if provided, is ignored). +If multiple keys are provided, then they will all be tried in turn, unless +the token includes the "kid" header field, in which case only the +specified key will be used. If an authorisation server is specified, then the default client, after it prompts for a password, will request a token from the authorisation server diff --git a/group/description.go b/group/description.go index 4af6967..19e575a 100644 --- a/group/description.go +++ b/group/description.go @@ -581,7 +581,7 @@ func SetWildcardUser(group string, user *UserDescription) error { func SetKeys(group string, keys []map[string]any) error { if keys != nil { - _, err := token.ParseKeys(keys) + _, err := token.ParseKeys(keys, "") if err != nil { return err } diff --git a/token/jwt.go b/token/jwt.go index bc6f8fe..9ee8f7e 100644 --- a/token/jwt.go +++ b/token/jwt.go @@ -96,14 +96,18 @@ func ParseKey(key map[string]any) (any, error) { } } -func ParseKeys(keys []map[string]any) ([]jwt.VerificationKey, error) { - ks := make([]jwt.VerificationKey, len(keys)) - for i, ky := range keys { +func ParseKeys(keys []map[string]any, kid string) ([]jwt.VerificationKey, error) { + ks := make([]jwt.VerificationKey, 0, len(keys)) + for _, ky := range keys { + // return all keys if kid is not specified + if kid != "" && ky["kid"] != kid { + continue + } k, err := ParseKey(ky) if err != nil { return nil, err } - ks[i] = k + ks = append(ks, k) } return ks, nil } @@ -130,11 +134,15 @@ func toStringArray(a interface{}) ([]string, bool) { func parseJWT(token string, keys []map[string]any) (*JWT, error) { t, err := jwt.Parse( token, - func(t *jwt.Token) (interface{}, error) { - ks, err := ParseKeys(keys) + func(t *jwt.Token) (any, error) { + kid, _ := t.Header["kid"].(string) + ks, err := ParseKeys(keys, kid) if err != nil { return nil, err } + if len(ks) == 1 { + return ks[0], nil + } return jwt.VerificationKeySet{Keys: ks}, nil }, jwt.WithExpirationRequired(),