我正在使用PyJWT来解码来自keycloft的JWT令牌。
eyJhbGciOiJSUzi1NiIsInR5cIgOiAiSldUIiwia2lkIiA6ICJ6MWpiUExrndMVTBkTHk3a0NIT1pyS2FJd3FPMXFrbThDeGtvVHg2QzFBIn0.eyJleHAiOjE2MjE0MjQwMjEsImlhdCI6MTYyMTQyMzk2MSSwiYXV0aF90aW1lIjoxNjIxNDIxNzc0LCJqdGkiOiIwYzY2Y2I0My1lMGY1LTQzNjItc2MS1lN2OW VhNDM5MjUILJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIwiYXVkIjpbIM1Hc1yzWFsbSIsImFjY291bnQiXSwic3ViIjoiN2Y2ODBlN2MtZGM4Yy00ZGJiLWJiZDEtMTE0ZGJhYjA2Zjc1IidHlwIjoiQmVhcmVyIiwiYXPwIjoiYW11bmRzW4tZnJvbnRlbmQiLCJzZXNzaW9uX3N0YXRlIjoiYTM5YzJlNmUtZGNjMS00OTM5LTg0ODITYzk2NGE5ODMxNmYyIiwiNyYWIjoiMSIsImFsbG93ZWQtb3JpZ2lucy6WyJodHRwOi8vbG9jYWb3N0OjUwMDAi LCJsb2NhbGhvc3Q6NTAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9ZXMiOlsiY3JlYXRlLXJlYWxtIiwb2ZmbGluZV9hy2Nlc3MiLCJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXjZV9h Y2Nlc3miOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbInZpZXctcmVhbG0iLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYxRlLWNsaWVudCIsIm1hbmFnZS11c2VycyISIn1ZXJ5LXJlyWxtyIsInzpZXctYXV0aG9XpyahdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycysIm1hbmFnZS1ldmVudHMi LCJtYW5hZ2UtcmVhbG0i LCJ2aWV3LWV2ZW50cysInZpZXctdXNlcnMi LCJ2a WV3LWNsaWVud HMi LCjtYW5HZ2UtYXv0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIwicXVlcnktZ3JvdXBzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIM1hbmFnZS1hY2Nvdw50IwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYwlsIwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiYwrt aW5maXzdCBhZG1bmxhc3QiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiImdpdmVuX25hbWUioiJhZF1bmZpcn0IiwiZmFtaWx5X25hbWuiOiJwZG1bmyxc3QiLCjlbWFpbCI6ImFkbWludGVzdEBnbWFpbC5jb20ifQ.aksSjBU5hJ1rtn43NtbMt8E6gaGmJXDrtGDI7j0T7eo6AcnUxG4spYNNhyksXVr3ZFvua2WyTKnZirqaJUI3zzdLj-XkE7zYCYwoJpjXITmmlj5oszD3pcRdGeyUVyQV49tiUfUFi1KoIt9K016mH2s_beFrN3TYSjuLh5Epdk_dpNBh9YE_1f3pwsEbN2Jgz_j-VB6cQHq17RzWQIVSd6ZvftAWDWdc 6nobOvTy1mZAA_DgsXwdjuNc8Qv36ztuDzkT-raCnuLH479ciBOFQZ0946obIE4ddJKpr7lnVupcbQZ6lDM_QZHz1hwkYqgSU-Ui8NHaWlqt4HJ5-9A
我的代码
import jwt
import traceback
try:
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhlOIQLHXwZoS3w9SBtvZ1ea4ftWmWnP+HCwlvs7XoJ9EhS+ZQEP7Z25tjW3I8mjUVL0XETrOOjQsD8O2nRBqizJsRaB8L9xsXdJmPHVTx7nphaBPtY5YHxxYqpwEC5rAKtx54YJxw6Ggeicmv+xXtaaDf/VALh5xxpa1U6yP5oqk3yV27yA0beQFVsdugkcfYN0C2FldaUcF9yTUf/KNHTYSu3Ar7iN9U+qEHwaznrLShwh7iknldTKTgEw3liHL8K/5ZlqxHPsL02InwZMaIRic3zNIgVvwedroM6nqZBB4mi1+T0dZn4qsNkG4D0w7IE7MTRgyyYARqrGEq5yOFwIDAQAB
-----END PUBLIC KEY-----"""
secret_key = "base-flask-oidc-secret-key"
token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ6MWpiUExrTndMVTBkTHk3a0NIT1pyS2FJd3FPMXFrbThDeGtvVHg2QzFBIn0.eyJleHAiOjE2MjE0MjQwMjEsImlhdCI6MTYyMTQyMzk2MSwiYXV0aF90aW1lIjoxNjIxNDIxNzc0LCJqdGkiOiIwYzY2Y2I0My1lMGY1LTQzNjItYTc2MS1lN2M2OWVhNDM5MjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwiYXVkIjpbIm1hc3Rlci1yZWFsbSIsImFjY291bnQiXSwic3ViIjoiN2Y2ODBlN2MtZGM4Yy00ZGJiLWJiZDEtMTE0ZGJhYjA2Zjc1IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYW11bmRzZW4tZnJvbnRlbmQiLCJzZXNzaW9uX3N0YXRlIjoiYTM5YzJlNmUtZGNjMS00OTM5LTg0ODItYzk2NGE5ODMxNmYyIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJsb2NhbGhvc3Q6NTAwMCJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiY3JlYXRlLXJlYWxtIiwib2ZmbGluZV9hY2Nlc3MiLCJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsibWFzdGVyLXJlYWxtIjp7InJvbGVzIjpbInZpZXctcmVhbG0iLCJ2aWV3LWlkZW50aXR5LXByb3ZpZGVycyIsIm1hbmFnZS1pZGVudGl0eS1wcm92aWRlcnMiLCJpbXBlcnNvbmF0aW9uIiwiY3JlYXRlLWNsaWVudCIsIm1hbmFnZS11c2VycyIsInF1ZXJ5LXJlYWxtcyIsInZpZXctYXV0aG9yaXphdGlvbiIsInF1ZXJ5LWNsaWVudHMiLCJxdWVyeS11c2VycyIsIm1hbmFnZS1ldmVudHMiLCJtYW5hZ2UtcmVhbG0iLCJ2aWV3LWV2ZW50cyIsInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJtYW5hZ2UtYXV0aG9yaXphdGlvbiIsIm1hbmFnZS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIGVtYWlsIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiYWRtaW5maXJzdCBhZG1pbmxhc3QiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImdpdmVuX25hbWUiOiJhZG1pbmZpcnN0IiwiZmFtaWx5X25hbWUiOiJhZG1pbmxhc3QiLCJlbWFpbCI6ImFkbWludGVzdEBnbWFpbC5jb20ifQ.aksSjBU5hJ1rtn43NtbMt8E6gaGmJXDrtGDI7j0T7eo6PAcnUxG4spYNNhyksXVr3ZFvua2WyTKnZirqaJUI3zzdLj-XkE7zYCYWoJpjXITmmlj5oszD3pcRdGeyUVyQV49tIiUfUFi1KoIt9K016mH2s_beFrN3TYSjuLh5Epdk_dpNBh9YE_1f3opwsEbN2Jgz_j-VB6cQHq17RzWQIVSd6ZvftAWDWdc6nobOvTy1mZAA_DgsXwdjuNc8Qv36ztuDzkT-raCnuLH479ciBOFQZ0946obIE4ddJKpr7lnVupcbQZ6lDM_QZHz1hwkYqgSU-Ui8NHaWlqt4HJ5-9A"
# token_json = jwt.decode(token, secret_key, algorithms=['HS256', 'RS256'], audience='account')
token_json = jwt.decode(token, public_key, algorithms=['HS256', 'RS256'], audience='account')
print(access_token_json)
except Exception:
print(traceback.print_exc())
据jwt.io报道,它显示的是头标
{
"alg": "RS256",
"typ": "JWT",
"kid": "z1jbPLkNwLU0dLy7kCHOZrKaIwqO1qkm8CxkoTx6C1A"
}
我试过使用公钥和私钥,两者都给了我错误
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 232, in _verify_signature
alg_obj = self._algorithms[alg]
KeyError: 'RS256'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "jwt_test.py", line 16, in <module>
access_token_json = jwt.decode(access_token, public_key, algorithms=['HS256', 'RS256'], audience='account')
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
**kwargs,
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 149, in decode_complete
self._verify_signature(signing_input, header, signature, key, algorithms)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 239, in _verify_signature
raise InvalidAlgorithmError("Algorithm not supported")
jwt.exceptions.InvalidAlgorithmError: Algorithm not supported
如果我正在从算法列表中删除"RS256"。
token_json = jwt.decode(token, public_key, algorithms=['HS256'], audience='account')
那我就错了。
Traceback (most recent call last):
File "jwt_test.py", line 18, in <module>
token_json = jwt.decode(token, public_key, algorithms=['HS256'], audience='account')
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 119, in decode
decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jwt.py", line 95, in decode_complete
**kwargs,
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 149, in decode_complete
self._verify_signature(signing_input, header, signature, key, algorithms)
File "/usr/local/lib/python3.7/site-packages/jwt/api_jws.py", line 229, in _verify_signature
raise InvalidAlgorithmError("The specified alg value is not allowed")
我该如何解决这个问题。
提前感谢!
###################回答####################
我能够通过解决它
按照@KlausD在评论中的建议安装加密
pip install cryptography
还将公钥更改为
public_key = """-----BEGIN PUBLIC KEY-----nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhlOIQLHXwZoS3w9SBtvZ1ea4ftWmWnP+HCwlvs7XoJ9EhS+ZQEP7Z25tjW3I8mjUVL0XETrOOjQsD8O2nRBqizJsRaB8L9xsXdJmPHVTx7nphaBPtY5YHxxYqpwEC5rAKtx54YJxw6Ggeicmv+xXtaaDf/VALh5xxpa1U6yP5oqk3yV27yA0beQFVsdugkcfYN0C2FldaUcF9yTUf/KNHTYSu3Ar7iN9U+qEHwaznrLShwh7iknldTKTgEw3liHL8K/5ZlqxHPsL02InwZMaIRic3zNIgVvwedroM6nqZBB4mi1+T0dZn4qsNkG4D0w7IE7MTRgyyYARqrGEq5yOFwIDAQABn-----END PUBLIC KEY-----"""
再次阅读PyJWT安装指南后,似乎对于某些签名算法,如RSA,需要安装python密码库。
我通过安装dependency:解决了这个问题
pip install pyjwt[crypto]
我也遇到了同样的问题(Mac上的Python版本3.6.7),但解决方案完全不同,除了一些其他步骤外,我还通过提供的答案解决了这个问题。
注意:不要认为,如果您激活了虚拟环境并使其长期处于活动状态,它将以与我们期望的相同的效率工作。因此,即使你的电脑、笔记本电脑、系统等处于睡眠模式,也要确保重新激活它。
看看下面我到底面对了什么,并最终解决了这个问题。
我是如何生成Private&公钥
下面是要执行的两个命令,以获得private&公钥。
> openssl genrsa -out jwt-key 4096
> openssl rsa -in jwt-key -pubout > jwt-key.pub
获取JWT(编码)
encoded_jwt = jwt.encode({ "user_id": 1 }, private_key, algorithm='RS256')
它在不同虚拟环境的项目中取得了成功。现在,我试图在另一个具有不同虚拟环境的项目中解码这个JWT(该项目几天前已经激活,并且仍然处于活动状态)。
payload = jwt.decode(encoded_jwt, public_key, algorithms=['RS256'])
并看到了此错误/异常消息。
3.6/site-packages/jwt/api_jws.py", line 226, in _verify_signature
raise InvalidAlgorithmError('Algorithm not supported')
jwt.exceptions.InvalidAlgorithmError: Algorithm not supported
哎呀!让我们试着解决它!
我是如何解决的
在阅读了答案后,我按照步骤在我已经激活的虚拟环境中安装了pyjwt[crypto]
、cryptography
(任何一个)包,但我的问题也没有得到解决。这让我考虑尝试另一种算法,但我想尝试并集思广益寻找其他解决方案。
我只是查看了<virtualenv_dir>/lib/site-packages/
内部,发现没有安装cryptography
包,而是在实际的Python环境中安装在外部。
因此,现在,我有了一些解决问题的想法,并执行了以下步骤来解决问题。
- 已停用虚拟环境
- 运行
pip uninstall pyjwt[crypto]
- 运行
pip uninstall cryptography
- 激活虚拟环境
- 运行
pip install pyjwt[crypto]
- 运行
pip install cryptography
现在,当我解码编码的JWT时,它工作得很好。
解码JWT
> payload = jwt.decode(encoded_jwt, public_key, algorithms=['RS256'])`
> payload
{ "user_id": 1 }
最后,这个错误得到了解决。
这里解释了发生错误的原因。你可以解决这个问题,只需避免检查jwt:的受众数据
import jwt
ALGORITHM = "HS256"
options={
'verify_exp': False, # Skipping expiration date check
'verify_aud': False
}
try:
payload = jwt.decode(token, YOUR_SECRET_KEY, algorithms=[ALGORITHM], options=options)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))