您好,我想知道如何获取密钥来验证访问令牌。我从 https://login.microsoftonline.com/{{tenantid}}/discovery/keys?appid={{app-id}}
获得了 x5c但是如果我把这个密钥放入 jwt-decode 函数中,它就会失败。我需要对这个键进行一些处理吗?它是公钥,我需要知道私钥来验证签名还是只需要公钥就足够了。
您能告诉我一些验证 access_token 的基本算法吗?
我的 Azure 访问令牌、私钥的签名验证?
我同意 Junnas 的评论,您需要公钥来使用 Azure 访问令牌验证签名。
您可以使用以下代码使用
PyJwt
库使用公钥解码访问令牌。
代码:
import requests
import jwt
from cryptography.hazmat.primitives import serialization
import json
tenant_id = 'xxxx'
client_id = 'xxxx'
client_secret = 'xxxxx'
token_endpoint = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
data = {
"grant_type": "client_credentials",
"client_id": f"{client_id}",
"client_secret": f"{client_secret}",
"scope": "api://your-client-id/.default"
}
response = requests.post(token_endpoint, data=data)
access_token = response.json()["access_token"]
print(access_token)
response1 = requests.get("https://login.microsoftonline.com/fb134080-e4d2-45f4-9562-f3a0c218f3b0/discovery/keys")
keys = response1.json()['keys']
token_headers = jwt.get_unverified_header(response.json()['access_token'])
token_alg = token_headers['alg']
token_kid = token_headers['kid']
public_key = None
for key in keys:
if key['kid'] == token_kid:
public_key = key
rsa_pem_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(public_key))
rsa_pem_key_bytes = rsa_pem_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
decoded_token = jwt.decode(
response.json()['access_token'],
key=rsa_pem_key_bytes,
verify=True,
options={"verify_signature": True},
algorithms=['RS256'],
audience="api://client_id",
issuer="https://sts.windows.net/tenant_id/"
)
s = json.dumps(decoded_token)
q = json.dumps(json.loads(s), indent=2)
print(q)
输出:
{
"aud": "api://xxxxx",
"iss": "https://sts.windows.net/xxxx",
"iat": 169028xxx,
"nbf": 1690284xxx,
"exp": 1690371xxx,
"aio": "E2ZgYFDetxxxxxvq/ydjjk/BwA=",
"appid": "d8xxxxx",
"appidacr": "1",
"idp": "https://sts.windows.net/xxxxx,
"oid": "dxxxxx",
"rh": "xxxxx",
"roles": [
"tread.all"
],
"sub": "dxxxxxx5",
"tid": "fxxx",
"uti": "wJxxxxxA",
"ver": "1.0"
}
注意: 如果您使用 MS Graph API 范围
https://graph.microsoft.com/.default
,结果 JWT 将在 JWT 标头中包含“随机数”,并且不意味着要进行验证。除非您拥有 API 范围。
参考:
jwt - 使用 Azure AD 租户 ID - 以及为“应用程序注册”颁发的有效令牌。签名验证失败 - Stack Overflow by rukmini.