【问题标题】:TokenValidator in `django-cognito-jwt` get_public_key method returns None`django-cognito-jwt` get_public_key 方法中的 TokenValidator 返回无
【发布时间】:2020-03-29 09:48:08
【问题描述】:

我正在关注aws-cognito-tutorial-complete 并尝试将Bearer 与 Django 一起使用,因为我的目标是使用 Django REST 框架和 GraphQL 的单页应用程序 (SPA)。

通过给定的示例,我可以连接 AWS 并能够注册、登录等到 AWS Cognito。然后我使用django-cognito-jwt 来解码 Bearer 令牌。

问题:
django-cognito-jwt 引发有关公钥问题的错误

尝试:
TokenValidator 类与方法 _get_public_key

令牌在那里

     35     def _get_public_key(self, token):
     36         import ipdb; ipdb.set_trace()
---> 37         try:
     38             headers = jwt.get_unverified_header(token)
     39         except jwt.DecodeError as exc:
     40             raise TokenError(str(exc))
     41
     42         if getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_ENABLED", False):

ipdb> token
b'eyJraWQiOiJUaGd4NXo5MnFxNjdPR1wvMDRjT0xDS2U2K0dsQlU3XC9LZklHK2hJdFwvSjR3PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIyZTQ3OTBhMC0zNWE0LTQ1ZDctYjEwYy1jZWQ3OWJlMjJlOTQiLCJhdWQiOiIxNTl1ZmpyaWhnZWhiNjdzbjM3M2FvdGxpNyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJldmVudF9pZCI6ImM2OTA0NjYyLWZlOWUtNGYwZi04OTc3LTdhZGU4M2YyOTAxMyIsInRva2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNTc1NDU3MDIwLCJpc3MiOiJodHRwczpcL1wvY29nbml0by1pZHAudXMtd2VzdC0yLmFtYXpvbmF3cy5jb21cL3VzLXdlc3QtMl9mbENKYW9EaWciLCJjb2duaXRvOnVzZXJuYW1lIjoiam9obi1yYW1ibyIsImV4cCI6MTU3NTQ2MDYyMCwiaWF0IjoxNTc1NDU3MDIwLCJlbWFpbCI6ImZvZ2d5Z2lnYUBnbWFpbC5jb20ifQ.jk207sDdYb7CDhc5r0hZXa_EDPqG9Fi2oBTot8Tv_moJxdB1v4cNCDLB6m5rVVHzmxI8-cPj00GViMH3-LORnQcg4KitAlew_aD_RMD5Hzy3ltABrMYBf9LEI2kq6---Li9jk3NYpVji2h5W4oKoJrHRriJSuNuBFFijFXEc29iLhQclaDLWvXw4BJI087BKCYpnD-xR79bM3nYI-m9Wp40e_e7JbsGtu1JKfTym_nKLE-yncyhWq0rarIbauBHmq5hRYCQofUbSWD6IRGCZaiLRPBTk6LvUd3VigUz9x0mIU8feViRQmFcVFfRsB56Pbx10RUAUYHBR4JNHCMROpQ'

转到headers旁边

ipdb> headers
{'kid': 'Thgx5z92qq67OG/04cOLCKe6+GlBU7/KfIG+hIt/J4w=', 'alg': 'RS256'}
ipdb> cache_key
'django_cognito_jwt:Thgx5z92qq67OG/04cOLCKe6+GlBU7/KfIG+hIt/J4w='

jwk_dataNone

ipdb> self._json_web_keys
{'D2syaFjXXpkbzTjkRHLAtdX065Neb1EfUguGabpJWlo=': '{"alg": "RS256", "e": "AQAB", "kid": "D2syaFjXXpkbzTjkRHLAtdX065Neb1EfUguGabpJWlo=", "kty": "RSA", "n": "kDmz5mTlTil_r6sVMnln2ohc45_TlBPw1pOcVJtEyGW2_vXN4EXnYKxcFyFQqZIjXaYlrAFBAMAW_qlIfJ0J8coyNImLngfUbk1cbwwQr3wTB-6t8bM8x_B8D_D7uB-HfGe8SNS1yFU6gfDnd4z7kJZvJIFV_uEWP5A1cbXdTOTPlj3zKUXnpXBvnZ5d_V2Y3gPjlv_m3uh3ZejeTAnaLF-PGt69DdD9dj04ncqPa2rK8eShPWYckZ_oaH_4Ju9FmQGD6lzoUHhRxEsfq6pEr2wFt2TAcji9WG7NUFO5v83GRfaWiRnGSVI8iVzVWjzzGvdqAuiMgKUDtmq7b9r5Xw", "use": "sig"}', 'a7tocHhrCduYr7EFRiR9A2txhEbl2dCOOBvYAYEdEJA=': '{"alg": "RS256", "e": "AQAB", "kid": "a7tocHhrCduYr7EFRiR9A2txhEbl2dCOOBvYAYEdEJA=", "kty": "RSA", "n": "re0iYlsRqmSkoqZiGlz3mTYb0HJ3vjCXwN83OmbNQyAguC-Tflb95Z1bEJsVL0Wr6ZvmFFGpXjJU1n3K9DO2JadnBQkGsJegYvXaNC2IgHnHDq9chrP6cNdnO5jAo7wqtMeZi2VqccyRFXVx9dyKAbyGgborORP5raFSvHU-qT2iVfwrbSbWXAH1qwkwbMMbU6fUHJp7u9ZrJT04qMhm-asgoSA6Swe4znqcg87W2dSWMzstyUQwTN-1Kn2GXmTIyYo4lUIoyQRXyl2d8L37iTkbRayulvLqvzkKglAHlRF6jLLHLZt6-ZBf3hvISDbO5Vwo7jJGTYYu6h3tKKbSBQ", "use": "sig"}'}
ipdb> headers["kid"]
'Thgx5z92qq67OG/04cOLCKe6+GlBU7/KfIG+hIt/J4w='

此时jwk_dataNone

> /Users/sarit/.pyenv/versions/muy/lib/python3.7/site-packages/django_cognito_jwt/validator.py(48)_get_public_key()
     47                 jwk_data = self._json_web_keys.get(headers["kid"])
---> 48                 timeout = getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_TIMEOUT", 300)
     49                 cache.set(cache_key, jwk_data, timeout=timeout)

ipdb> jwk_data
ipdb>

解决方法:
放大token_validator.validate(jwt_token)

class JSONWebTokenAuthentication(BaseAuthentication):
    """Token based authentication using the JSON Web Token standard."""

    def authenticate(self, request):
        """Entrypoint for Django Rest Framework"""
        jwt_token = self.get_jwt_token(request)
        if jwt_token is None:
            return None
        # Authenticate token
        try:
            token_validator = self.get_token_validator(request)
            jwt_payload = token_validator.validate(jwt_token)
        except TokenError:
            raise exceptions.AuthenticationFailed()

        USER_MODEL = self.get_user_model()
        user = USER_MODEL.objects.get_or_create_for_cognito(jwt_payload)
        return (user, jwt_token)

放大self._get_public_key(token)

    def validate(self, token):
        public_key = self._get_public_key(token)
        if not public_key:
            raise TokenError("No key found for this token")

        try:
            jwt_data = jwt.decode(
                token,
                public_key,
                audience=self.audience,
                issuer=self.pool_url,
                algorithms=["RS256"],
            )
        except (jwt.InvalidTokenError, jwt.ExpiredSignature, jwt.DecodeError) as exc:
            raise TokenError(str(exc))
        return jwt_data

放大jwt.get_unverified_header(token)

    def _get_public_key(self, token):
        try:
            headers = jwt.get_unverified_header(token)
        except jwt.DecodeError as exc:
            raise TokenError(str(exc))

        if getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_ENABLED", False):
            cache_key = "django_cognito_jwt:%s" % headers["kid"]
            jwk_data = cache.get(cache_key)

            if not jwk_data:
                jwk_data = self._json_web_keys.get(headers["kid"])
                timeout = getattr(settings, "COGNITO_PUBLIC_KEYS_CACHING_TIMEOUT", 300)
                cache.set(cache_key, jwk_data, timeout=timeout)
        else:
            jwk_data = self._json_web_keys.get(headers["kid"])

        if jwk_data:
            return RSAAlgorithm.from_jwk(jwk_data)

放大_jwt_global_obj.get_unverified_header

get_unverified_header = _jwt_global_obj.get_unverified_header

放大self._load(jwt)

    def get_unverified_header(self, jwt):
        """Returns back the JWT header parameters as a dict()

        Note: The signature is not verified so the header parameters
        should not be fully trusted until signature verification is complete
        """
        headers = self._load(jwt)[2]
        self._validate_headers(headers)

        return headers

self._load(jwt) 方法。我发现我可以正确解压 Congito 令牌中的值

ipdb> from pprint import pprint
ipdb> pprint(self._load(jwt))
(b'{"sub":"2e4790a0-35a4-45d7-b10c-ced79be22e94","aud":"159ufjrihgehb67sn373aot'
 b'li7","email_verified":true,"event_id":"c6904662-fe9e-4f0f-8977-7ade83f29013"'
 b',"token_use":"id","auth_time":1575457020,"iss":"https:\\/\\/cognito-idp.us'
 b'-west-2.amazonaws.com\\/us-west-2_flCJaoDig","cognito:username":"john-ram'
 b'bo","exp":1575460620,"iat":1575457020,"email":"xxxx@gmail.com"}',
 b'eyJraWQiOiJUaGd4NXo5MnFxNjdPR1wvMDRjT0xDS2U2K0dsQlU3XC9LZklHK2hJdFwvSjR3PSIs'
 b'ImFsZyI6IlJTMjU2In0.eyJzdWIiOiIyZTQ3OTBhMC0zNWE0LTQ1ZDctYjEwYy1jZWQ3OWJlMjJl'
 b'OTQiLCJhdWQiOiIxNTl1ZmpyaWhnZWhiNjdzbjM3M2FvdGxpNyIsImVtYWlsX3ZlcmlmaWVkIjp0'
 b'cnVlLCJldmVudF9pZCI6ImM2OTA0NjYyLWZlOWUtNGYwZi04OTc3LTdhZGU4M2YyOTAxMyIsInRv'
 b'a2VuX3VzZSI6ImlkIiwiYXV0aF90aW1lIjoxNTc1NDU3MDIwLCJpc3MiOiJodHRwczpcL1wvY29n'
 b'bml0by1pZHAudXMtd2VzdC0yLmFtYXpvbmF3cy5jb21cL3VzLXdlc3QtMl9mbENKYW9EaWciLCJj'
 b'b2duaXRvOnVzZXJuYW1lIjoiam9obi1yYW1ibyIsImV4cCI6MTU3NTQ2MDYyMCwiaWF0IjoxNTc1'
 b'NDU3MDIwLCJlbWFpbCI6ImZvZ2d5Z2lnYUBnbWFpbC5jb20ifQ',
 {'alg': 'RS256', 'kid': 'Thgx5z92qq67OG/04cOLCKe6+GlBU7/KfIG+hIt/J4w='},
 b'\x8eM\xb4\xee\xc0\xdda\xbe\xc2\x0e\x179\xafHY]\xaf\xc4\x0c\xfa\x86\xf4X\xb6'
 b'\xa0\x14\xe8\xb7\xc4\xef\xfej\t\xc5\xd0u\xbf\x87\r\x082\xc1\xeankUQ\xf3'
 b'\x9b\x12<\xf9\xc3\xe3\xd3A\x95\x88\xc1\xf7\xf8\xb3\x91\x9d\x07 \xe0\xa8'
 b'\xad\x02W\xb0\xfd\xa0\xffD\xc0\xf9\x1f<\xb7\x96\xd0\x01\xac\xc6\x01\x7f'
 b'\xd2\xc4#i*\xeb\xef\xbe./c\x93sX\xa5X\xe2\xda\x1eV\xe2\x82\xa8&\xb1\xd1\xae"'
 b'R\xb8\xdb\x81\x14X\xa3\x15q\x1c\xdb\xd8\x8b\x85\x07%h2\xd6\xbd|8\x04\x92'
 b'4\xf3\xb0J\t\x8ag\x0f\xecQ\xef\xd6\xcc\xdev\x08\xfaoV\xa7\x8d\x1e\xfd\xee'
 b'\xc9n\xc1\xad\xbbRJ}<\xa6\xfer\x8b\x13\xec\xa7s(V\xabJ\xda\xac\x86'
 b'\xda\xb8\x11\xe6\xab\x98Q`$(}F\xd2X>\x88D`\x99j"\xd1<\x14\xe4\xe8\xbb\xd4'
 b'wub\x81L\xfd\xc7I\x88S\xc7\xdeV$P\x98W\x15\x15\xf4l\x07\x9e\x8fo\x1dtE'
 b'@\x14`pQ\xe0\x93G\x08\xc4N\xa5')

我可能会以自己的方式破解并从 self._load(jwt) 此处创建用户

问题:
1. 如何在这里获取公钥?
2.是django-cognito-jwt的bug吗?

【问题讨论】:

    标签: python django jwt amazon-cognito


    【解决方案1】:

    我的错。我配置了错误的“REGION、USER_POOL_ID 和 APP_CLIENT_ID” 我需要使用id token

    【讨论】:

      猜你喜欢
      • 2018-10-02
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多