| 75 | } |
| 76 | |
| 77 | func (a *API) parseJWTClaims(bearer string, r *http.Request) (context.Context, error) { |
| 78 | ctx := r.Context() |
| 79 | config := a.config |
| 80 | |
| 81 | p := jwt.NewParser(jwt.WithValidMethods(config.JWT.ValidMethods)) |
| 82 | token, err := p.ParseWithClaims(bearer, &AccessTokenClaims{}, func(token *jwt.Token) (interface{}, error) { |
| 83 | if kid, ok := token.Header["kid"]; ok { |
| 84 | if kidStr, ok := kid.(string); ok { |
| 85 | key, err := conf.FindPublicKeyByKid(ctx, kidStr, &config.JWT) |
| 86 | if err != nil { |
| 87 | return nil, err |
| 88 | } |
| 89 | if key != nil { |
| 90 | return key, nil |
| 91 | } |
| 92 | |
| 93 | // otherwise try to use fallback |
| 94 | } |
| 95 | } |
| 96 | if alg, ok := token.Header["alg"]; ok { |
| 97 | if alg == jwt.SigningMethodHS256.Name { |
| 98 | // preserve backward compatibility for cases where the kid is not set |
| 99 | return []byte(config.JWT.Secret), nil |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | return nil, fmt.Errorf("unrecognized JWT kid %v for algorithm %v", token.Header["kid"], token.Header["alg"]) |
| 104 | }) |
| 105 | if err != nil { |
| 106 | return nil, apierrors.NewForbiddenError(apierrors.ErrorCodeBadJWT, "invalid JWT: unable to parse or verify signature, %v", err).WithInternalError(err) |
| 107 | } |
| 108 | |
| 109 | return withToken(ctx, token), nil |
| 110 | } |
| 111 | |
| 112 | func (a *API) maybeLoadUserOrSession(ctx context.Context) (context.Context, error) { |
| 113 | db := a.db.WithContext(ctx) |