mozilla/mozilla-django-oidc

Authentication backend get_userinfo incorrectly assumes the endpoint responds with application/json

sergei-maertens opened this issue ยท 7 comments

return user_response.json()

This line tries to decode the response content as JSON, which is one of the ways this endpoint may be implemented. The other way is that it responds with a JWT, having a Content-Type header of application/jwt;charset=utf-8 and that fails to decode as JSON, as the JWT itself needs to be processed.

Environment details:

  • OS: Arch Linux
  • Python: 3.10
  • Django: 3.2 LTS
  • mozilla-django-oidc: 3.0.0

How to reproduce:

  • Use an OIDC_OP_USER_ENDPOINT that responds with a JWT
  • Authenticate using OIDC
  • Observe JSONDecodeError crash

From an OIDC specification point of view, this a good point from @sergei-maertens. Under the 5.3.2 Successful UserInfo Response heading, here's what said about the application/jwt header:

If the UserInfo Response is signed and/or encrypted, then the Claims are returned in a JWT and the content-type MUST be application/jwt.

@akatsoulas are you working on this? I've got an implementation in our downstream package that I'd prefer to see contributed back upstream, so I can draft a PR.

I'm having the same problem now.

There also seem to be a few more reports about this:

The first of them was published almost four years ago.

@akatsoulas, can we hope that this will be fixed soon?

Awesome that you found these cross-references, I did search in the issue list but couldn't find anything.

Since I haven't heard back from @akatsoulas, I will just draft a PR with our implementation that can serve as a starting point, or at the least a way so that downstream packages can override the method in the backend to solve their own needs.

I have a draft PR #521 for this

Hey, @sergei-maertens are you still working on this? I have an implementation and would be super happy to offer it by the end of the week through a PR.

Well I have the attached PR asking for some review/input, so I'd say this is blocked by maintainer availability rather than by me