Проверьте JWT access_token из AAD Azure Fails - PullRequest
0 голосов
/ 28 ноября 2018

Мне нужно проверить azure jwt access_token из службы, над которой я работаю.В настоящее время мы делаем запрос к https://graph.microsoft.com/beta/me. Если запрос выполнен успешно, токен действителен.К сожалению, мы не сможем продолжать это делать.

Я испробовал множество идей для этого.Ни один из них с успехом.Даже jwt.io не распознает подпись, хотя jwt kid и kid из одной из доступных подписей в jwk_uri совпадают.

На основе этого блога post Я создал следующее решение (также доступно на 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()

Это решение возвращает Invalid Signature для действительного маркера access_token со следующей трассировкой:

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

Любые идеи о том, что я могу ошибаться, будут полезны.

1 Ответ

0 голосов
/ 30 ноября 2018

Обычно утверждение audience используется для указания на client_id клиентского приложения, зарегистрированного в Azure / Microsoft.Мне кажется, что ошибка происходит из-за несоответствия утверждений в jwt (вероятно, аудитория).Проверьте, правильно ли вы указали client_id для переменной аудитории.

...