在 Python 中使用来自 Gravitee 的公钥解码 JWT 令牌时出现问题
Posted
技术标签:
【中文标题】在 Python 中使用来自 Gravitee 的公钥解码 JWT 令牌时出现问题【英文标题】:Problem decoding JWT token with public key from Gravitee in Python 【发布时间】:2022-01-08 06:24:51 【问题描述】:我正在尝试使用公钥解码 Gravitee JWT 令牌。我已经测试了 PyJWT、authlib、python-jose 和 jwcrypto 库,并查看了此页面上的很多帖子,但我在所有帖子中都遇到了相同的错误,我无法解决问题。
错误:
('无法反序列化密钥数据。数据可能格式不正确,可能使用不受支持的算法加密,或者可能是不受支持的密钥类型(例如具有显式参数的 EC 曲线)。' , [_OpenSSLErrorWithText(code=151584876, lib=9, reason=108, reason_text=b'error:0909006C:PEM routines:get_name:no start line')])
首先我按照 Gravitee 的说明获得了公钥:
https://docs.gravitee.io/am/current/am_userguide_create_certificate.html
来自https://jwt.io 的关于我的令牌的一些信息:
HEADER:ALGORITHM & TOKEN TYPE
"kid": "default",
"alg": "RS256"
Python 软件包版本:
PyJWT==2.3.0(也用 2.1.0 测试过)
cryptography==36.0.0(一些帖子建议是必需的)
我的代码:
from rest_framework import permissions
from rest_framework.exceptions import APIException
from django.conf import settings
import jwt
class TokenNotValid(APIException):
status_code = 403
default_detail = "Invalid or absent JWT token field."
class NoAuthHeader(APIException):
status_code = 403
default_detail = "Absent 'Authorization' header."
class ValidJWTPermission(permissions.BasePermission):
"""
Global permission check for JWT token.
"""
def _get_pubkey(self):
key = """-----BEGIN PUBLIC KEY-----\n""" + settings.GRAVITEE_PUBLIC_KEY + """\n-----END PUBLIC KEY-----"""
return key
def has_permission(self, request, view):
auth_header = request.META.get('HTTP_AUTHORIZATION')
# print("Received header:")
# print(auth_header)
if auth_header is None:
raise NoAuthHeader
try:
token = auth_header.split()[1]
# print("Encoded Token:")
# print(token)
public_key = self._get_pubkey()
print(public_key)
claims = jwt.decode(token, key=public_key, algorithms=['RS256'])
claims.validate()
except Exception as e:
print(e)
raise TokenNotValid
# print("Decoded token:")
# print(dec_token)
return True
我还测试了像 key.encode()
和 key.encode('ascii')
这样的密钥编码,或者用“BEGIN RSA PUBLIC KEY”而不是“BEGIN PUBLIC KEY”组合密钥,任何东西都适合我。我总是有同样的错误。
【问题讨论】:
【参考方案1】:根据库的不同,您通常需要 JWK 格式的密钥,如以下链接所示: https://demo.identityserver.io/.well-known/openid-configuration/jwks
JSON Web Key (JWK) format 是处理令牌时表示键的标准,也许您的库也希望采用这种格式?
【讨论】:
感谢您的回复。图书馆想要 PEM 并且不支持 JWK 格式,我尝试了很多密钥格式的可能性,但它们中的任何一个都有效。 您是否使用 openssl 验证过您实际上可以读取密钥并且它是有效的?比如使用“openssl rsa -text -noout -pubin -in rsa-public-key.pem”以上是关于在 Python 中使用来自 Gravitee 的公钥解码 JWT 令牌时出现问题的主要内容,如果未能解决你的问题,请参考以下文章