【问题标题】:token verification failing using JWK/JWT for user authentication使用 JWK/JWT 进行用户身份验证的令牌验证失败
【发布时间】:2022-01-01 19:10:24
【问题描述】:

我正在尝试使用 python 中的公钥验证 idToken。

我首先将 JWK 令牌转换为 PEM,但是当我调用“解码”函数时,我看到“签名验证失败”异常。我错过了什么?

# Long string goes here - this is the token to verify
myToken = 'ezFraWQiXXX.YYYYYYYY.ZZZZZZZZ'

# JWK Token
webkey = {
      "alg": "RS256",
      "e": "AQAB",
      "kid": "d9FzOfniXuHf2sF3opIKZb0sW8Nuaa0d5d+AXXXXXXXX=",
      "kty": "RSA",
      "n": "nQwBvRlZKdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4HcenyO_WASyjr6korLEHxh8XXXXXXXXXXXX",
      "use": "sig"
    }

# Converting JWK to PEM
public_key = jwt.algorithms.RSAAlgorithm.from_jwk(webkey)
pubk_bytes = public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo)


# This is where I get the "signature verification failed" exception
claim = jwt.decode(myToken, pubk_bytes, algorithms=['RS256']) # <<-- ideally this should decode the token for me

【问题讨论】:

  • 我无法用发布的代码和我自己的数据重现问题。发布 test 数据:JWT 和 JWK。也许密钥不匹配,所以也将私钥发布到公钥。

标签: python oauth-2.0 jwt rsa jwk


【解决方案1】:

看起来您正在使用PyJWT,这是一个不错的安全库选择。理想情况下,让库从授权服务器的 JWKS 端点为您下载令牌签名公钥,以获得最干净和最简单的代码:

import jwt
from jwt import PyJWKClient

// The client will read the JWT header to get the kid field,
// then download token signing public keys and return that matching the kid.
// This key will then be cached for future JWTs with the same kid.
// The client will reliably handle new kids if keys are recycled.
jwks_client = PyJWKClient(url)
signing_key = jwks_client.get_signing_key_from_jwt(access_token_jwt)

// It is recommended to verify the signature, expiry, issuer and audience.
// As a best practice, the API should also specify the algorithms it expects
// to receive in JWT signatures.
claims = jwt.decode(
  access_token_jwt,
  signing_key.key,
  algorithms=["RS256"],
  issuer="my-issuer",
  audience="my-audience")

您应该能够将 JWK 直接发送到库中,而不是处理 RSA 或字节转换。有关一些示例,请参阅pyJWT docs。对于进一步的安全背景,您可能还会发现 JWT Best Practices 上的 Curity 文章很有用。

【讨论】:

  • 谢谢!以及如何找到解码功能的“发行者”和“受众”?
  • 发行者和受众通常在您发行令牌的地方定义 - 例如在授权服务器中。 Issuer 是代表 AS 的固定值, Audience 代表你的 API(或一组相关 API)——它可能是一个值,例如 api.mycompany.com。如果这些不存在,则将它们从您的 JWT 验证代码中排除。
  • 行得通!谢谢,@加里。现在我想看看如何使我的 idToken 生成非认知特定。在这里分别提出这些问题:stackoverflow.com/questions/70552022/…
猜你喜欢
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 2017-02-04
  • 2016-12-17
  • 1970-01-01
  • 2021-10-12
  • 2014-10-30
相关资源
最近更新 更多