-
Notifications
You must be signed in to change notification settings - Fork 1k
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
oauth2: cannot fetch token: 401 Unauthorized Response: {"code":null,"message":"Bad credentials"} #320
Comments
The client id and secret should be url encoded in the basic auth header. You may decode the clientSecret and clientID in the server side to solved the problem.
|
This also affects the combination with Cloud Foundry UAA and apparently quite some other OAuth servers, see cloudfoundry/uaa#778. The reason is that certain RFCs require encoding of the basic authentication header content, while others don't. |
UAA is most certainly doing the wrong thing by having their server not URL decode these, nor their various clients URL encode them. The RFC is unambiguous on this. I've pinged them multiple on multiples issues about this, however they seem quite content to not contemplate addressing the problem. That said, I also believe it would be better for an OAuth library use the
|
@aeijdenberg Thanks for this feedback :-) |
@heikoettelbruecksap - I stand by the comment that the RFCs are unambiguous and do not contradict. RFC6749#2.3.1 - Client Password states:
You are correct that neither RFC2617 - HTTP Authentication: Basic and Digest Access Authentication (which obsoletes RFC2069 - An Extension to HTTP : Digest Access Authentication) nor RFC1945 - Hypertext Transfer Protocol -- HTTP/1.0 contemplate URL encoding the username / password, however RFC6749#2.3.1 clearly states that the client identifier is to be encoded and that the encoded value be used as the username, and the same with the password. That is, it describes what is done to map the client ID / secret to the inputs needed by the basic auth encoding. So neither is wrong or ambiguous - they each correctly describe different layers of protocols. Of course, now that you have me reading RFCs, that same section also states:
which is a pretty decent argument to be made this library is already doing the right thing (at least per RFCs) and should not be changed. |
Your last finding is actually interesting and agree it gives some direction of how the ideal solution should behave (i.e. not pass the client credentials via request body).
|
@heikoettelbruecksap - I do agree a compatibility options makes sense, and it looks like others do too, as it exists already here: https://godoc.org/golang.org/x/oauth2#RegisterBrokenAuthHeaderProvider |
Although this header was base64 encoded, the oAuth spec requires that is also be url encoded. This was causing client credentials that contained special characters (e.g. `+`) to be rejected by UAA. See: > The client identifier is encoded using the "application/x-www-form-urlencoded" encoding algorithm per Appendix B, and the encoded value is used as the username; the client password is encoded using the same algorithm and used as the password. https://tools.ietf.org/html/rfc6749#section-2.3.1 Related: golang/oauth2#320 [#171268188](https://www.pivotaltracker.com/story/show/171268188_
Although this header was base64 encoded, the oAuth spec requires that is also be url encoded. This was causing client credentials that contained special characters (e.g. `+`) to be rejected by UAA. See: > The client identifier is encoded using the "application/x-www-form-urlencoded" encoding algorithm per Appendix B, and the encoded value is used as the username; the client password is encoded using the same algorithm and used as the password. https://tools.ietf.org/html/rfc6749#section-2.3.1 Related: golang/oauth2#320 [#171268188](https://www.pivotaltracker.com/story/show/171268188)
workaround to deal with golang/oauth2#320
workaround to deal with golang/oauth2#320
workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server
workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
Co-authored-by: 3v1n0 <[email protected]> workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
Co-authored-by: 3v1n0 <[email protected]> workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
Workaround to deal with golang/oauth2#320 tldr is that IDP servers tend to not be fully compliant with how client credentials are passed and have bespoke arrangements so anything goes this enforces the standard implementation from the RFC and has it working for any RFC compliant OIDC server full info here golang/oauth2#320
13449ad
The commit 'internal: urlencode client id and secret in header' with ID: 13449ad
throws an error 'oauth2: cannot fetch token: 401 Unauthorized' when the clientID or the clienteSecret contains a special characters.
See line 191 of the internal/token.go
req.SetBasicAuth(clientID, clientSecret) is changed into req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))
Our client consists of implementation of get oauth2 token:
For example, we are developing a client oauth2 with client_credentials as grant_type and clientServer was something like 'word1/word2'. So clientSecret != url.QueryEscape(clientSecret)
'word1/word2' != word1%2Fword2 get a response {"code":null,"message":"Bad credentials"}
The text was updated successfully, but these errors were encountered: