You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by ma...@apache.org on 2022/12/16 14:12:41 UTC

[kafka] branch KAFKA-14496-fix-oauth-encoder created (now eb53c4c8c7e)

This is an automated email from the ASF dual-hosted git repository.

manikumar pushed a change to branch KAFKA-14496-fix-oauth-encoder
in repository https://gitbox.apache.org/repos/asf/kafka.git


      at eb53c4c8c7e KAFKA-14496: Wrong Base64 encoder used by OIDC OAuthBearerLoginCallbackHandler

This branch includes the following new commits:

     new eb53c4c8c7e KAFKA-14496: Wrong Base64 encoder used by OIDC OAuthBearerLoginCallbackHandler

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[kafka] 01/01: KAFKA-14496: Wrong Base64 encoder used by OIDC OAuthBearerLoginCallbackHandler

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

manikumar pushed a commit to branch KAFKA-14496-fix-oauth-encoder
in repository https://gitbox.apache.org/repos/asf/kafka.git

commit eb53c4c8c7e5eb1e8a39139a1f7d3e0d1860fe67
Author: Kirk True <kt...@confluent.io>
AuthorDate: Thu Dec 15 15:37:36 2022 -0800

    KAFKA-14496: Wrong Base64 encoder used by OIDC OAuthBearerLoginCallbackHandler
    
    The OAuth code to generate the Authentication header was incorrectly
    using the URL-safe base64 encoder. For client IDs and/or secrets with
    dashes and/or plus signs would not be encoded correctly, leading to the
    OAuth server to reject the credentials.
    
    This change uses the correct base64 encoder, per RFC-7617.
    
    Co-authored-by: Endre Vig <ve...@gmail.com>
---
 .../internals/secured/HttpAccessTokenRetriever.java       |  3 ++-
 .../internals/secured/HttpAccessTokenRetrieverTest.java   | 15 ++++++++++++---
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetriever.java b/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetriever.java
index 78917de6f1e..2e61449304d 100644
--- a/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetriever.java
+++ b/clients/src/main/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetriever.java
@@ -344,7 +344,8 @@ public class HttpAccessTokenRetriever implements AccessTokenRetriever {
         clientSecret = sanitizeString("the token endpoint request client secret parameter", clientSecret);
 
         String s = String.format("%s:%s", clientId, clientSecret);
-        String encoded = Base64.getUrlEncoder().encodeToString(Utils.utf8(s));
+        // Per RFC-7617, we need to use the *non-URL safe* base64 encoder. See KAFKA-14496.
+        String encoded = Base64.getEncoder().encodeToString(Utils.utf8(s));
         return String.format("Basic %s", encoded);
     }
 
diff --git a/clients/src/test/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetrieverTest.java b/clients/src/test/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetrieverTest.java
index a193545fd38..5086a1dab29 100644
--- a/clients/src/test/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetrieverTest.java
+++ b/clients/src/test/java/org/apache/kafka/common/security/oauthbearer/internals/secured/HttpAccessTokenRetrieverTest.java
@@ -173,10 +173,19 @@ public class HttpAccessTokenRetrieverTest extends OAuthBearerTest {
 
     @Test
     public void testFormatAuthorizationHeader() throws IOException {
-        String expected = "Basic " + Base64.getUrlEncoder().encodeToString(Utils.utf8("id:secret"));
+        assertAuthorizationHeader("id", "secret");
+    }
 
-        String actual = HttpAccessTokenRetriever.formatAuthorizationHeader("id", "secret");
-        assertEquals(expected, actual);
+    @Test
+    public void testFormatAuthorizationHeaderEncoding() throws IOException {
+        // See KAFKA-14496
+        assertAuthorizationHeader("SOME_RANDOM_LONG_USER_01234", "9Q|0`8i~ute-n9ksjLWb\\50\"AX@UUED5E");
+    }
+
+    private void assertAuthorizationHeader(String clientId, String clientSecret) throws IOException {
+        String expected = "Basic " + Base64.getEncoder().encodeToString(Utils.utf8(clientId + ":" + clientSecret));
+        String actual = HttpAccessTokenRetriever.formatAuthorizationHeader(clientId, clientSecret);
+        assertEquals(expected, actual, String.format("Expected the HTTP Authorization header generated for client ID \"%s\" and client secret \"%s\" to match", clientId, clientSecret));
     }
 
     @Test