Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

userinfo signature algorithms #376

Open
matchaxnb opened this issue Oct 1, 2020 · 3 comments
Open

userinfo signature algorithms #376

matchaxnb opened this issue Oct 1, 2020 · 3 comments

Comments

@matchaxnb
Copy link

matchaxnb commented Oct 1, 2020

Version: mozilla-django-oidc==1.2.4

Hello,

I have noticed the userinfo endpoint works only when the userinfo signature algorithm is set to "unsigned" (in Keycloak).

Indeed the code to get the userinfo after login is

    def get_userinfo(self, access_token, id_token, payload):
        """Return user details dictionary. The id_token and payload are not used in
        the default implementation, but may be used when overriding this method"""

        user_response = requests.get(
            self.OIDC_OP_USER_ENDPOINT,
            headers={
                'Authorization': 'Bearer {0}'.format(access_token),
                'Accept': 'application/json',
            },
            verify=self.get_settings('OIDC_VERIFY_SSL', True),
            timeout=self.get_settings('OIDC_TIMEOUT', None),
            proxies=self.get_settings('OIDC_PROXY', None))
        user_response.raise_for_status()
        return user_response.json()

There is no decoding step of the response and the library expects the response from the OIDC server to be unsigned unencrypted json while it may very well be a signed payload.

Would _verify_jws be a good starting point to support signed payloads from the userinfo endpoints?

@strus38
Copy link

strus38 commented Oct 31, 2020

Hi

You saved my day ... I encounter this exact issue - and opened this defect: [https://github.com//issues/383] since the error message is quite not obvious!... so it will probably end up as a dupliacte of yours.
With you change, it works better indeed.
Thanks, I wish I saw it before!

@rhclayto
Copy link

rhclayto commented Dec 27, 2021

@strus38

What change makes this work? I have the same problem.


Edit: My working code change below. (Works with Authelia OpenID provider.) In auth.py

import json
def get_userinfo(self, access_token, id_token, payload):
        """Return user details dictionary. The id_token and payload are not used in
        the default implementation, but may be used when overriding this method"""

        user_response = requests.get(
            self.OIDC_OP_USER_ENDPOINT,
            headers={
                'Authorization': 'Bearer {0}'.format(access_token)
            },
            verify=self.get_settings('OIDC_VERIFY_SSL', True),
            timeout=self.get_settings('OIDC_TIMEOUT', None),
            proxies=self.get_settings('OIDC_PROXY', None))
        user_response.raise_for_status()
        msg = user_response.text
        utf8 = msg.encode('utf-8')
        jws = JWS.from_compact(utf8)
        jwsjson = json.loads(jws.payload)
        return jwsjson

@kirodh
Copy link

kirodh commented Jun 6, 2024

@strus38

What change makes this work? I have the same problem.

Edit: My working code change below. (Works with Authelia OpenID provider.) In auth.py

import json
def get_userinfo(self, access_token, id_token, payload):
        """Return user details dictionary. The id_token and payload are not used in
        the default implementation, but may be used when overriding this method"""

        user_response = requests.get(
            self.OIDC_OP_USER_ENDPOINT,
            headers={
                'Authorization': 'Bearer {0}'.format(access_token)
            },
            verify=self.get_settings('OIDC_VERIFY_SSL', True),
            timeout=self.get_settings('OIDC_TIMEOUT', None),
            proxies=self.get_settings('OIDC_PROXY', None))
        user_response.raise_for_status()
        msg = user_response.text
        utf8 = msg.encode('utf-8')
        jws = JWS.from_compact(utf8)
        jwsjson = json.loads(jws.payload)
        return jwsjson

Can the developers please incorporate this into the code as it works. And its a pain to edit the code for docker setups.

In the mean time I have pulled the repo and are pulling it privately with the fix. Thank you for this package,its the only thing that works for me with the keycloak and django integration.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants