[英]Validate JWT access_token from AAD Azure Fails
我需要從我正在處理的服務中驗證一個 azure jwt access_token。 我們目前正在向https://graph.microsoft.com/beta/me發出請求。 如果請求成功,則令牌有效。 不幸的是,我們將無法繼續這樣做。
為此,我嘗試了各種想法。 他們都沒有成功。 即使jwt.io不認簽名,即使智威湯遜kid
和kid
從可用的簽名之一jwk_uri匹配。
在此基礎上博客后我已經創建了一個下面的解決方案(也GitHub上可用) 。
我的實現與博客文章非常相似,但有一些變化:
#!/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()
此解決方案為具有以下追溯的有效 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
關於我可能出錯的任何想法都會有所幫助。
我遇到了類似的問題,經過幾天的調查,我發現在我的案例中,我正在請求具有內置范圍(openid 和配置文件)的令牌,並且沒有任何自定義范圍,這導致發布具有不同受眾的令牌(MS Graph)和因此用不同的公鑰簽名的令牌(因為我認為發出的 access_token 只是委托的 MS Graph 范圍的一個轉發)。
我通過在我的應用程序注冊(公開 API 部分)中添加一個自定義范圍解決了這個問題,現在我的 access_tokens 以有效的受眾發布,我可以用我的應用程序公鑰檢查簽名。
通常, audience
聲明用於指向您在 Azure/Microsoft 中注冊的客戶端應用程序的client_id
。 在我看來,錯誤是由於jwt
(可能是受眾)中的聲明不匹配而發生的。 檢查您是否為受眾變量設置了正確的client_id
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.