Сообщение об ошибке
token signature is invalid: signing method ES256 is invalid
Также выводится как
- signing method ES256 is invalid
- token signature is invalid: signing method HS256 is invalid
- token is unverifiable: signing method (alg) is unavailable
v4 выводит «signing method ES256 is invalid». Значение `alg`, которое golang-jwt вообще не знает (или `none` без специальной константы), вместо этого даёт «token is unverifiable: signing method (alg) is unavailable».
golang-jwt/jwt (Go) — WithValidMethods rejected the token's alg
Что это означает
Значения заголовка `alg` токена нет в списке, который вы передали через `jwt.WithValidMethods`, поэтому golang-jwt отклонил токен ещё до обращения к ключу из вашей Keyfunc. Эта проверка нужна, потому что заголовок контролирует атакующий: допустимый алгоритм выбирает проверяющая сторона, а не токен. v5 относит эту ошибку к `ErrTokenSignatureInvalid`, поэтому она выглядит как неверная подпись, но на самом деле это отказ по политике алгоритмов.
Почему это происходит
Издатель сменил алгоритм
частоПоставщики удостоверений переходят с RS256 на ES256 или добавляют ключи EdDSA. Проверяющие стороны, жёстко закрепившие старый алгоритм, с момента переключения отклоняют каждый новый токен.
Список разрешённых алгоритмов скопирован из другого сервиса
иногдаОбщий middleware, настроенный для одного издателя (RS256), повторно используется для другого, который подписывает алгоритмом ES256. Список разрешённых алгоритмов должен соответствовать издателю, чьи токены проверяет именно эта проверяющая сторона.
Чужой токен или пробный запрос
иногдаТокены с `alg: HS256` или `none`, приходящие в API с RS256/ES256, типичны для попыток подмены алгоритма. Продолжайте их отклонять.
Как исправить
- 1.
Разрешите ровно тот алгоритм, который использует издатель
Посмотрите JWKS издателя (`alg` каждого ключа) или его документ обнаружения (`id_token_signing_alg_values_supported`) и закрепите эти значения. На время миграции укажите оба алгоритма и выбирайте ключи по `kid`.
go token, err := jwt.Parse(raw, keyfunc, jwt.WithValidMethods([]string{"ES256"}), // what the issuer signs with today jwt.WithIssuer("https://issuer.example.com/"), ) - 2.
Проверяйте тип метода в Keyfunc
Проверка конкретного типа `t.Method` в Keyfunc гарантирует, что ключ ECDSA будет использоваться только с алгоритмом ECDSA, даже если список разрешённых алгоритмов позже расширят.
go keyfunc := func(t *jwt.Token) (any, error) { // Belt and braces: the key type must fit the algorithm family. if _, ok := t.Method.(*jwt.SigningMethodECDSA); !ok { return nil, fmt.Errorf("unexpected signing method %v", t.Header["alg"]) } return lookupKey(t.Header["kid"]) }