pennersr / django-allauth

Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.
https://allauth.org
MIT License
9.54k stars 3.03k forks source link

How does `_get_apple_public_key` of `AppleOAuth2Adapter` returns None? #3518

Closed ramchandra-st closed 6 months ago

ramchandra-st commented 12 months ago

I came across issues, where the _get_apple_public_key private method returns None even though it receives kid value from the caller. I believe the code from _get_apple_public_key didn't find the d from data for the given kid (So this means, we don't have a public key for the given kid).

        for d in data["keys"]:
            if d["kid"] == kid:
                return d

So my question is, in what sort of scenarios this issue occurs?

Some code queries from this module: https://github.com/pennersr/django-allauth/blob/main/allauth/socialaccount/providers/apple/views.py#L52C63-L52C63

       def get_public_key(self, id_token):
        """
        Get the public key which matches the `kid` in the id_token header.
        """
        kid = jwt.get_unverified_header(id_token)["kid"]
        apple_public_key = self._get_apple_public_key(kid=kid)

        public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(apple_public_key))
        return public_key

And caller defintion of above

    def get_verified_identity_data(self, id_token):
        provider = self.get_provider()
        allowed_auds = self.get_client_id(provider)

        try:
            public_key = self.get_public_key(id_token)
            identity_data = jwt.decode(
                id_token,
                public_key,
                algorithms=["RS256"],
                audience=allowed_auds,
                issuer="https://appleid.apple.com",
            )
            return identity_data

        except jwt.PyJWTError as e:
            raise OAuth2Error("Invalid id_token") from e

It handles jwt.PyJWTError, but get_public_key could raise AttributeError if we get apple_public_key is None.

With django-allauth==0.55.2

pennersr commented 6 months ago

I do not know under what circumstances the key cannot be found. Though, the above mentioned code has undergone some refactoring, and it now does recognize that scenario:

    key = lookup(keys_data, kid)
    if not key:
        raise OAuth2Error(f"Invalid 'kid': '{kid}'")

So it is now handled as far as we can on our end.