By: David Avendasora user 08 Jan 2018 at 3:32 p.m. CST

3 Responses
David Avendasora gravatar
According to the OAuth 2.0 spec ([RFC 6749](https://tools.ietf.org/html/rfc6749), section [2.3.1](https://tools.ietf.org/html/rfc6749#section-2.3.1)) When using Basic Authentication for client authentication, the `Client ID` and `Client Secret` must **first** be individually [URL-encoded](https://tools.ietf.org/html/rfc6749#appendix-B) before they can be used for Basic Authentication, see: [RFC 2617, Section 2](https://tools.ietf.org/html/rfc2617#section-2). In simple terms, OAuth 2.0 client authentication requires **additional work** to be done by both the client (URL-encoding) and authentication server (URL-decoding) when using HTTP Basic Authentication. This requirement for two-step encoding/decoding is further clarified in a July 2016 [RFC errata entry](https://www.rfc-editor.org/errata_search.php?rfc=6749&eid=4749), which changes Section [2.3.1](https://tools.ietf.org/html/rfc6749#section-2.3.1) to read (**_change emphasized_**): > Clients in possession of a client password MAY use the HTTP Basic authentication scheme as defined in [RFC2617](https://tools.ietf.org/html/rfc2617) to authenticate with the authorization server. The client identifier is encoded using the "application/x-www-form-urlencoded" encoding algorithm per [Appendix B](https://tools.ietf.org/html/rfc6749#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 url encoded values are then encoded as defined in [RFC2617]_**. The authorization server MUST support the HTTP Basic authentication scheme for authenticating clients that were issued a client password. And includes the following note by the author: > It was not clear to some implementers that the intention is a 2-step encoding. First for special characters and second the 2617 base 64 encoding. Implementers thought 6749 was in conflict with 2617. ### Example: - **Client ID:** `@!12AD!0008!6D30.23D7` (note the `@` and `!`) - **Client Secret:** `P@55W0rd!` Must be URL-encoded to be used for Basic Authentication's `user-id` and `password`: - **RFC 2617 userid:** `%40%2112AD%210008%216D30.23D7` - **RFC 2617 password:** `P%4055W0rd%21` When combined (`userid:password`), and then base64 encoded as defined in [RFC 2617 Section 2](https://tools.ietf.org/html/rfc2617#section-2): - **RFC 2617 user-pass:** `%40%2112AD%210008%216D30.23D7:P%4055W0rd%21` - **RFC 2617 base64-user-pass:** `JTQwJTIxMTJBRCUyMTAwMDglMjE2RDMwLjIzRDc6UCU0MDU1VzByZCUyMQ==` Produce the OAuth 2.0-**compliant** header field: - `Authorization: Basic JTQwJTIxMTJBRCUyMTAwMDglMjE2RDMwLjIzRDc6UCU0MDU1VzByZCUyMQ==` The 3.1.1 version of Gluu does not URL-decode the `userid` and `password` values extracted from the Authorization HTTP request header before using them as the `Client ID` and `Client Secret`, which means the following, not-fully-decoded values are used for authentication: - **Client ID:** `%40%2112AD%210008%216D30.23D7` - **Client Secret:** `P%4055W0rd%21` Which fails. ### Work Around If neither the `Client ID` nor `Client Secret` contain special characters (which would have been encoded by URL-encoding) then Authentication **will still succeed**, thereby seeming to be compliant. Unfortunately, Gluu's auto-generated OIDC `Client ID`s (`Inum`s) do contain special characters, however the `Inum` can be _carefully_ modified in the LDAP server using a tool such as [Apache Directory Studio](http://directory.apache.org/studio). ### Summary I believe that Gluu (and likely oxd-java, but I haven't tested it) are **not** in compliance with the OAuth 2.0 specification because it does not correctly handle Basic Authentication for client authentication. See also: - [https://github.com/GluuFederation/oxAuth/issues/677](https://github.com/GluuFederation/oxAuth/issues/677) - [https://support.gluu.org/authentication/4908/token-endpoint-with-basic-authentication-fails-due-to-not-url-decoding/](https://support.gluu.org/authentication/4908/token-endpoint-with-basic-authentication-fails-due-to-not-url-decoding/) References: - [https://tools.ietf.org/html/rfc6749](https://tools.ietf.org/html/rfc6749) - [https://tools.ietf.org/html/rfc2617](https://tools.ietf.org/html/rfc2617)

By Michael Schwartz Account Admin 08 Jan 2018 at 3:42 p.m. CST

Michael Schwartz gravatar
We'll look at the impact of fixing this. We've known about the issue for some time. Basic auth is not the only work around. We support a few authn mechanisms at the token endpoint, including client_secret_post, client_secret_jwt, and private_key_jwt.

By David Avendasora user 09 Jan 2018 at 9:13 a.m. CST

David Avendasora gravatar
Thanks for the clarification, Michael. I really appreciate the quick answer! `client-secret-post` is also supported by [Spring Security 5.0.0](https://docs.spring.io/spring-security/site/docs/5.0.0.RELEASE/api/org/springframework/security/oauth2/core/ClientAuthenticationMethod.html) for requesting the access token. I'll verify that it is a valid work-around for me. If not, I'll look at modifying the OxAuth codebase and creating a pull request.

By Javier Rojas staff 26 Jan 2018 at 12:36 p.m. CST

Javier Rojas gravatar
https://github.com/GluuFederation/oxAuth/issues/677#issuecomment-360866197 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= ``` https://github.com/GluuFederation/oxAuth/commit/227f79d8aba8e5a7c15151eb4083243e583aa308#diff-58a42c9f996cf0170d1de06a81d5580fR87 ``` 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 ```