[英]Validate JWT access_token from AAD Azure Fails
I need to validate a azure jwt access_token from the service I'm working on.我需要从我正在处理的服务中验证一个 azure jwt access_token。 We are currently making a request to https://graph.microsoft.com/beta/me .
我们目前正在向https://graph.microsoft.com/beta/me发出请求。 If the request succeeded, the token is valid.
如果请求成功,则令牌有效。 Unfortunately we will not be able to keep doing that.
不幸的是,我们将无法继续这样做。
I have tried a variety of ideas for this.为此,我尝试了各种想法。 None of them with success.
他们都没有成功。 Even jwt.io does not recognize the signature, even though jwt
kid
and the kid
from one of the available signatures in jwk_uri matches.即使jwt.io不认签名,即使智威汤逊
kid
和kid
从可用的签名之一jwk_uri匹配。
Based on this blog post I have created a following solution (also available on github) .在此基础上博客后我已经创建了一个下面的解决方案(也GitHub上可用) 。
My implementation is very similar to the blog post with a few changes:我的实现与博客文章非常相似,但有一些变化:
#!/usr/bin/env python2
import jwt
import requests
import sys
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend
def get_public_key(access_token):
""" Retrieve public key for access token """
token_header = jwt.get_unverified_header(access_token)
res = requests.get('https://login.microsoftonline.com/common/.well-known/openid-configuration')
jwk_uri = res.json()['jwks_uri']
res = requests.get(jwk_uri)
jwk_keys = res.json()
x5c = None
# Iterate JWK keys and extract matching x5c chain
for key in jwk_keys['keys']:
if key['kid'] == token_header['kid']:
x5c = key['x5c']
break
else:
raise Exception('Certificate not found in {}'.format(jwk_uri))
cert = ''.join([
'-----BEGIN CERTIFICATE-----\n',
x5c[0],
'\n-----END CERTIFICATE-----\n',
])
try:
public_key = load_pem_x509_certificate(cert.encode(), default_backend()).public_key()
except Exception as error:
raise Exception('Failed to load public key:', error)
return public_key, key['kid']
def main():
print '\n'
if len(sys.argv) < 2 or '-h' in sys.argv:
print 'Run it again passing acces token:\n\tpython jwt_validation.py <access_token>'
sys.exit(1)
access_token = sys.argv[1]
audience = 'https://graph.microsoft.com'
public_key, kid = get_public_key(access_token)
try:
jwt.decode(
access_token,
public_key,
algorithms='RS256',
audience=audience,
)
except Exception as error:
print 'key {} did not worked, error:'.format(kid), error
sys.exit(1)
print('Key worked!')
if __name__ == '__main__':
main()
This solution returns Invalid Signature
for a valid access_token with the following traceback:此解决方案为具有以下追溯的有效 access_token 返回
Invalid Signature
:
Traceback (most recent call last):
File "jwt_validation/jwt_validation.py", line 63, in <module>
main()
File "jwt_validation/jwt_validation.py", line 57, in main
audience=audience,
File "~/.pyenv/versions/jwt-validation-tool/lib/python2.7/site-packages/jwt/api_jwt.py", line 93, in decode
jwt, key=key, algorithms=algorithms, options=options, **kwargs
File "~/.pyenv/versions/jwt-validation-tool/lib/python2.7/site-packages/jwt/api_jws.py", line 157, in decode
key, algorithms)
File "~/.pyenv/versions/jwt-validation-tool/lib/python2.7/site-packages/jwt/api_jws.py", line 224, in _verify_signature
raise InvalidSignatureError('Signature verification failed')
jwt.exceptions.InvalidSignatureError: Signature verification failed
Any ideas of what I could be wrong would be helpful.关于我可能出错的任何想法都会有所帮助。
I ran into simillar issue, after couple of days investigating I've found in my case that I am requesting token with built in scopes (openid and profile) and without any custom scope which results in issuing tokens with different audiance (MS Graph) and hence tokens signed with with different public key (because I think that issued access_token is just a forward of the delegated MS Graph scope).我遇到了类似的问题,经过几天的调查,我发现在我的案例中,我正在请求具有内置范围(openid 和配置文件)的令牌,并且没有任何自定义范围,这导致发布具有不同受众的令牌(MS Graph)和因此用不同的公钥签名的令牌(因为我认为发出的 access_token 只是委托的 MS Graph 范围的一个转发)。
I resolved the issue by adding a custom scope in my app registration (Expose API section) and now my access_tokens are issued with valid audiance and I am able to check signature with my app public key.我通过在我的应用程序注册(公开 API 部分)中添加一个自定义范围解决了这个问题,现在我的 access_tokens 以有效的受众发布,我可以用我的应用程序公钥检查签名。
Usually the audience
claim is used to point to the client_id
of the client application you have registered in Azure/Microsoft.通常,
audience
声明用于指向您在 Azure/Microsoft 中注册的客户端应用程序的client_id
。 Looks to me that the error is occurring due to a mismatch of claims in jwt
(probably audience).在我看来,错误是由于
jwt
(可能是受众)中的声明不匹配而发生的。 Check whether you have set the correct client_id
for the audience variable.检查您是否为受众变量设置了正确的
client_id
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.