[英]How to validate a JWT from AzureAD in python?
I have set up an authorization server using AzureAD.我已经使用 AzureAD 设置了授权服务器。 For testing it I am currently applying an implicit flow and to get a token and id_token I use https://oidcdebugger.com/ .
为了测试它,我目前正在应用隐式流并获取令牌和 id_token 我使用https://oidcdebugger.com/ 。
Now I am trying to figure out how to properly validate a the token on the resource server side.现在我想弄清楚如何正确验证资源服务器端的令牌。 I always get a
jose.exceptions.JWTError: Signature verification failed
.我总是收到
jose.exceptions.JWTError: Signature verification failed
。 Can you help me find out what I am doing wrong?你能帮我找出我做错了什么吗? I am really new to JWT validation and probably there is some obvious error somwhere.
我对 JWT 验证真的很陌生,可能在某个地方存在一些明显的错误。
As defined by the OIDC metadata endpoint at https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration
keys for signature validation can be found at https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys
.如
https://login.microsoftonline.com/{tenant_id}/v2.0/.well-known/openid-configuration
的 OIDC 元数据端点所定义,用于签名验证的密钥可在https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys
。 The key ids on that endpoint match the kid
value in my token headers.该端点上的密钥 ID 与我的令牌标头中的
kid
值匹配。 So, I am positive that those are my keys.所以,我很肯定这些是我的钥匙。 They look like this:
它们看起来像这样:
{
"kty": "RSA",
"use": "sig",
"kid": "<the-key-id>",
"x5t": "<the-key-id>",
"n": "<a-long-hash>",
"e": "AQAB",
"x5c": ["<a-long-hash-I-guess-thats-the-public-key"],
"issuer": "https://login.microsoftonline.com/<my-tenant-id>/v2.0"
}
In the answer of this post the key is constructed by hand using cryptography.x509
.在这篇文章的答案中,密钥是使用
cryptography.x509
手工构建的。 I tried the same but I had to change a few details to make it run.我尝试了同样的方法,但我必须更改一些细节才能使其运行。 I am
.encode
ing the string and I have to pass an iterable to the decode
function.我是
.encode
字符串,我必须将一个可迭代传递给decode
function。
import requests
from jose import jwt
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
AZURE_TENANT_ID = '<my-tenant-id>'
AZURE_KEYS = requests.get(url='<my-jwks_url>').json()['keys']
PEMSTART = "-----BEGIN CERTIFICATE-----\n"
PEMEND = "\n-----END CERTIFICATE-----\n"
def decode(token: str, keys: list):
token_header = jwt.get_unverified_header(token=token)
x5t = token_header['x5t']
key = [d for d in keys if d['x5t'] == x5t][0]
mspubkey = key['x5c'][0]
cert_str = PEMSTART + mspubkey + PEMEND
cert_obj = load_pem_x509_certificate(cert_str.encode(), default_backend())
public_key = cert_obj.public_key()
return jwt.decode(
token=token,
subject='<my-subject>',
audience='<my-audience>',
issuer=f'https://sts.windows.net/{AZURE_TENANT_ID}/',
algorithms=['RS256'],
key=[public_key])
It seems like I am not supposed to validate the (access) token, only the id_token signature.似乎我不应该验证(访问)令牌,只验证 id_token 签名。 The validation with
jose
also works by just supplying the key dict as keys
argument (no need to construct certificate).使用
jose
的验证也可以通过仅提供密钥 dict 作为keys
参数来工作(无需构造证书)。
Apparently the (access) token from AzureAD is not necessarily a standard JWT.显然,来自 AzureAD 的(访问)令牌不一定是标准的 JWT。 It's just supposed to be used for accessing the MS GraphAPI: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609#issuecomment-529537264
它只应该用于访问 MS GraphAPI: https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609#issuecomment-529537264
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.