IdentityModel / oidc-client-js

OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Apache License 2.0
2.43k stars 842 forks source link

Customize content type when querying /userinfo #1315

Open krzema12 opened 3 years ago

krzema12 commented 3 years ago

Hi Team!

I'm using the library to integrate with my company's internal SSO. Due to some historical reasons, the service responds to userinfo endpoint with content-type: text/plain when requested with Accept: */*. In such case, the library crashes as it expects content-type: application/json:

image

image

While our SSO could possibly respond with content-type: application/json and the problem would disappear, that's a though topic because it requires ensuring that no existing SSO clients will be broken because of such change. In the meantime, I'd like to request a possibility to customize the content type (or any other header field?) when making requests from this library.

FWIW: I use this library through a React wrapper https://github.com/bjerkio/oidc-react, but looking at its code, it doesn't deal with raw network calls - it literally wraps oidc-client-js. That's why I think any customization needs to be exposed here first.

Best, Piotr

krzema12 commented 3 years ago

Looking into the code:

https://github.com/IdentityModel/oidc-client-js/blob/deed90c95a52c4f5e812bf4a527d0b36eeeea1d9/src/JsonService.js#L54-L58

I think the library doesn't specify any headers in the request, but specifies some legal content types in response. So next to customizing request content type, another idea would be to allow text/plain or anything there. Then the JSON deserialization could be attempted and if it fails, then bubble up the failure to the user. Otherwise, if the request comes with content-type: whatever-that-deserializes-successfully-to-JSON, simply deserialize and carry on. It would give more flexibility to OAuth2 server implementations, and such little discrepancies are known to cause headaches.

krzema12 commented 3 years ago

I found a workaround. I set loadUserInfo to false and it appears that user data from a response from /token call is put in useAuth().userData. I then deserialize the JWT token from access_token and extract what I need.

This issue is still worth discussing because not in every case such simplification can be done.