Mensagem de erro
Signature verification failed (JWT::VerificationError)
Também aparece como
- JWT::VerificationError: Signature verification failed
Sem tratamento, o Ruby imprime a localização seguida de “Signature verification failed (JWT::VerificationError)”; o texto é o mesmo no ruby-jwt 2.10 e no 3.3.
ruby-jwt (Ruby) — JWT::VerificationError from JWT.decode
O que significa
O ruby-jwt decodificou o token e verificou a assinatura com a chave que você passou, e a verificação falhou. O token está bem formado e o algoritmo é permitido; a chave não pertence ao signatário, ou o token foi alterado. `JWT::VerificationError` é uma subclasse de `JWT::DecodeError`, então `rescue JWT::DecodeError` a captura junto com os erros de token malformado.
Por que acontece
A chave configurada não é a do signatário
comumUma chave pública de outro ambiente, uma chave desatualizada depois de uma rotação ou um par de chaves gerado de novo a cada inicialização em uma configuração de desenvolvimento que acabou chegando à produção.
Verificação com a chave errada de um JWKS
ocasionalPegar `keys.first` do JWKS de um emissor funciona até o emissor assinar com outra chave. Deixe o ruby-jwt escolher pelo `kid` com a opção `jwks:`.
Segredos HMAC diferentes
ocasionalAplicações Rails costumam derivar o segredo de `secret_key_base`; um serviço que usa outro valor — ou o mesmo valor com uma quebra de linha no final — calcula um MAC diferente.
Como corrigir
- 1.
Escolher as chaves pelo kid no JWKS do emissor
A opção `jwks:` aceita uma função de carregamento; o ruby-jwt a chama de novo com `kid_not_found: true` quando o token indica uma chave desconhecida, e assim as rotações são detectadas.
ruby require "jwt" require "net/http" jwks_loader = ->(options) do @jwks = nil if options[:kid_not_found] && @jwks_loaded_at.to_i < Time.now.to_i - 300 # refetch on rotation @jwks ||= begin @jwks_loaded_at = Time.now.to_i JSON.parse(Net::HTTP.get(URI("https://issuer.example.com/.well-known/jwks.json"))) end end payload, header = JWT.decode(token, nil, true, algorithms: ["ES256"], jwks: jwks_loader, iss: "https://issuer.example.com/", verify_iss: true) - 2.
Comprovar que as chaves correspondem
Hashes idênticos das metades públicas descartam a chave como causa; depois, procure alterações no token em trânsito.
bash openssl pkey -in issuer-private.pem -pubout | sha256sum openssl pkey -pubin -in configured-public.pem | sha256sum # must be identical