使用 JWK/JWT 进行用户身份验证的令牌验证失败
token verification failing using JWK/JWT for user authentication
我正在尝试使用 python 中的 public 密钥验证 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
看起来你正在使用 PyJWT,这是一个不错的安全库选择。理想情况下,让库从授权服务器的 JWKS 端点为您下载令牌签名 public 密钥,以获得最干净和最简单的代码:
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 for some examples. For further security background, you may also find the Curity article on JWT Best Practices有用。
我正在尝试使用 python 中的 public 密钥验证 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
看起来你正在使用 PyJWT,这是一个不错的安全库选择。理想情况下,让库从授权服务器的 JWKS 端点为您下载令牌签名 public 密钥,以获得最干净和最简单的代码:
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 for some examples. For further security background, you may also find the Curity article on JWT Best Practices有用。