Closed will-dee closed 6 years ago
There is a confusion in the specs because in rfc6749 it says:
Clients in possession of a client password MAY use the HTTP Basic
authentication scheme as defined in [RFC2617] to authenticate with
the authorization server. 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 The authorization server MUST support the HTTP Basic
authentication scheme for authenticating clients that were issued to
client password.
So the right way should be: auth_header = 'Basic' + base64 (urlEncode (client_id) + ':' + urlEncode (client_secret))
https://tools.ietf.org/html/rfc6749#section-2.3.1
But, in rfc2617 it says:
To receive authorization, the client sends the userid and password,
separated by a single colon (":") character, within a base64 [7]
encoded string in the credentials.
basic-credentials = base64-user-pass
base64-user-pass = <base64 [4] encoding of user-pass,
user-pass = userid ":" password
userid = * <TEXT excluding ":">
password = * TEXT
Userids might be case sensitive.
If the user agent wishes to send the userid "Aladdin" and password
"open sesame", it would use the following header field:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ ==
Base64 Decoding the example we got "open sesame" instead of "open% 20sesame". So the right way should be: auth_header = 'Basic' + base64 (client_id + ':' + client_secret)
https://tools.ietf.org/html/rfc2617#section-2
Anyway, I have modified the code in oxAuth Server and now it supports both rfc6749 and rfc2617 way.
Clarifying the above change, oxAuth is URL decoding the clientId and clientSecret so it will work with both cases:
Base64Encode(URLEncode(clientId) + ":" + URLEncode(clientSecret))
Base64Encode(clientId + ":" + clientSecret)
https://github.com/GluuFederation/oxAuth/commit/6431ada6ede8fa2e338b0f40896bf3f31a473333
username = URLDecoder.decode(token.substring(0, delim), Util.UTF8_STRING_ENCODING);
password = URLDecoder.decode(token.substring(delim + 1), Util.UTF8_STRING_ENCODING);
Also to make it more clear, I have added now a new test case using HTTP Basic Authentication in oxAuth with Url encoding client Id and client secret before perform the Base 64 encoding:
Base64Encode(URLEncode(clientId) + ":" + URLEncode(clientSecret))
Base64Encode(URLEncode("@!90CC.2E38.774C.610B!0001!FD3B.B0A0!0008!B011.91DC.5EAA.D899") + ":" + URLEncode("3fc14805-7bdb-4ce0-9861-f6ead000ac73"))
Base64Encode("%40%2190CC.2E38.774C.610B%210001%21FD3B.B0A0%210008%21B011.91DC.5EAA.D899" + ":" + "3fc14805-7bdb-4ce0-9861-f6ead000ac73")
Base64Encode("%40%2190CC.2E38.774C.610B%210001%21FD3B.B0A0%210008%21B011.91DC.5EAA.D899:3fc14805-7bdb-4ce0-9861-f6ead000ac73")
JTQwJTIxOTBDQy4yRTM4Ljc3NEMuNjEwQiUyMTAwMDElMjFGRDNCLkIwQTAlMjEwMDA4JTIxQjAxMS45MURDLjVFQUEuRDg5OTozZmMxNDgwNS03YmRiLTRjZTAtOTg2MS1mNmVhZDAwMGFjNzM=
POST /restv1/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: ce.gluu.info
Authorization: Basic JTQwJTIxOTBDQy4yRTM4Ljc3NEMuNjEwQiUyMTAwMDElMjFGRDNCLkIwQTAlMjEwMDA4JTIxQjAxMS45MURDLjVFQUEuRDg5OTozZmMxNDgwNS03YmRiLTRjZTAtOTg2MS1mNmVhZDAwMGFjNzM=
grant_type=authorization_code&code=f327363e-de4e-4408-ad18-6fadf4e3f32a&redirect_uri=https%3A%2F%2Fce.gluu.info%3A8443%2Foxauth-rp%2Fhome.htm
Support ticket: https://support.gluu.org/authentication/4947/token-endpoint-is-not-compliant-with-oauth-2-spec-for-basic-auth/
According to the OAuth2.0 spec, when doing auth code <-> token exchange the client ID and client secret should be url encoded prior to joining with a comma and then base46 encoding. For example:
However, oxAuth doesn't appear to respect the url encoding. If I try perform token exchange with the above authorisation header, I get a 401 error but if I instead compute the header without url encoding, the token exchange succeeds. For example:
The returned response body and Headers are as follows:
This issue only appears when using client IDs/secrets that use 'special' characters as simple alphanumeric strings are invariant under url encoding.