- Notifications
You must be signed in to change notification settings - Fork 586
Encode ClientId/Secret in Basic Authorization Header per OIDC Spec #1738
Conversation
- See 2.1.6.1 at http://openid.net/specs/openid-connect-basic-1_0.html#TokenRequest - Also removes the id and secret from the body of the message, although it's unclear if any Identity Providers will actually fail if its included both places, so might be worth leaving for compatibility even though it is against the spec. Addresses aspnet#1737
| Do you know of any services that don't work with the current bahavior? |
| And for that matter, any providers that this change works with? |
No, don't do that... it's illegal and standard-compliant servers will reject your request if you do that (e.g my 2 OIDC server libs will return a This change is a potential breaking change (if your credentials include a |
| This just cost our company an embarrassing amount of time and money to track down. It's mandated as optional in the OAUTH 2.0 spec, but required by the OIDC spec. Your current implementation isn't even allowed by the OIDC spec. |
| The identity provider for our company does not work if the client id and secret are included in the body. Any idp that does so is non-compliant. I would be surprised if the change actually breaks any providers, but if it does, then the bug is on their end. At the very least, the default behavior should be compliant, and a simple flag could be added to do it the old way. Why would a colon or non-ascii char in the id or secret cause a problem? The spec says that the authorization header should be base64 encoded, so putting the id and secret directly into the header separated by a colon would also be non-compliant. |
Sending the client credentials in the request form (aka
Wrong. Authorization servers can support
Heh no. Sending credentials in both the headers and the form is not allowed:
https://tools.ietf.org/html/rfc6749#section-2.3
https://tools.ietf.org/html/rfc6749#section-5.2
The identifier and the secret are separated by a Don't misinterpret what I'm saying: I believe the OIDC client handler should support basic authentication to deal with servers that only support this client authentication method. But it shouldn't be the default method because it would be a breaking change. |
Historically, most of the OAuth2/OpenID Connect servers have implemented client_id/client_secret deformatting the same exact way you did, which is sadly not compliant as both the client_id and the client_secret MUST be formurl-encoded before being concatenated. Otherwise, you'll end up with weird errors if either your client_id or your client_secret contains a Read https://tools.ietf.org/html/rfc7617#section-2 for more information. |
| My PR didn't actually send credentials in both header and form. I only mentioned it in the Issue, because I was trying to think of a way to keep everyone happy. I agree it's a bad idea. I didn't read the whole spec, but I (maybe mistakenly) thought the OIDC was trying to simplify interop by mandating client_secret_basic. I see what you mean now by the colon. I also did notice the failure to specify UTF8, although it seemed to be implied by other places I noticed in the spec that did specify UTF8. I'm well familiar with ambiguity problems in specs, having spent years making CORBA implementations interoperate. I also understand the resistance to making breaking changes. If I could get all of our (at least the newer core 2+) services to work out of the box with a one-line setting change instead of having to hack in a custom RedeemToken function then I would be very happy. Most of the teams at our company before me ended up either writing their own middleware from scratch, or even implementing the OIDC flows at the app layer with controllers. I've been pushing for our latest project to build all of our services relying on the stock core 2 middleware as much as possible. I don't want us to be in the OIDC/OAUTH business. |
| Just had a brief read through the full spec. Yikes. |
| For completeness, here's a link to the past discussion of this bug. #1032 |
| If the header is used for client authentication, it should use the encoding specified in RFC6749 - everything else is a bug. |
| @leastprivilege assuming you're referring to the formurl encoding, even that is quite risky as it has never been implemented correctly in many (if not most) OAuth2/OIDC implementations, including yours and mine 😅 |
| It's correctly implemented in IS4 (but yes - we got it wrong and fixed it recently). |
| Curious: did you do that in a major release or in a minor one? Did you implement a quirk? |
| minor. we got some error reports. People accepted it. My client lib has a "legacy mode". The world moved on. |
| I just checked the OIDC certification tests - they test that the OP supports both the authz header approach as well as POST body. So it's totally fine for the OIDC handler to POST client id/secret. BTW - the OIDC handler should get certified. I always tell customers to pick software from that list: |
| In summary: We could add this but it would need to be optional opt-in. Certification issue: https://github.com/aspnet/Security/issues/1197 |
| Triage discussion: While we think it could be good to support this, we are not taking this PR as-is because we think it needs to be opt-in (off by default, for compatibility), and we would likely also want to add additional test coverage. |
Addresses #1737