You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2020/06/20 04:46:42 UTC

[pulsar] branch master updated: Fix issue where HTTP header used in Athenz authentication can not be renamed (#7311)

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

mmerli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 82e3067  Fix issue where HTTP header used in Athenz authentication can not be renamed (#7311)
82e3067 is described below

commit 82e30678425f423dd28fead0ba8840d1c521ad61
Author: Masahiro Sakamoto <ma...@yahoo-corp.jp>
AuthorDate: Sat Jun 20 13:46:25 2020 +0900

    Fix issue where HTTP header used in Athenz authentication can not be renamed (#7311)
---
 .../client/impl/auth/AuthenticationAthenz.java     | 16 ++--
 .../client/impl/auth/AuthenticationAthenzTest.java | 89 ++++++++++++++--------
 2 files changed, 68 insertions(+), 37 deletions(-)

diff --git a/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java b/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java
index 3e0aef3..cf93064 100644
--- a/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java
+++ b/pulsar-client-auth-athenz/src/main/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenz.java
@@ -59,6 +59,7 @@ public class AuthenticationAthenz implements Authentication, EncodedAuthenticati
     private String providerDomain;
     private PrivateKey privateKey;
     private String keyId = "0";
+    private String roleHeader = null;
     // If auto prefetching is enabled, application will not complete until the static method
     // ZTSClient.cancelPrefetch() is called.
     // cf. https://github.com/yahoo/athenz/issues/544
@@ -80,7 +81,7 @@ public class AuthenticationAthenz implements Authentication, EncodedAuthenticati
     @Override
     synchronized public AuthenticationDataProvider getAuthData() throws PulsarClientException {
         if (cachedRoleTokenIsValid()) {
-            return new AuthenticationDataAthenz(roleToken, ZTSClient.getHeader());
+            return new AuthenticationDataAthenz(roleToken, isNotBlank(roleHeader) ? roleHeader : ZTSClient.getHeader());
         }
         try {
             // the following would set up the API call that requests tokens from the server
@@ -89,7 +90,7 @@ public class AuthenticationAthenz implements Authentication, EncodedAuthenticati
             RoleToken token = getZtsClient().getRoleToken(providerDomain, null, minValidity, maxValidity, false);
             roleToken = token.getToken();
             cachedRoleTokenTimestamp = System.nanoTime();
-            return new AuthenticationDataAthenz(roleToken, ZTSClient.getHeader());
+            return new AuthenticationDataAthenz(roleToken, isNotBlank(roleHeader) ? roleHeader : ZTSClient.getHeader());
         } catch (Throwable t) {
             throw new GettingAuthenticationDataException(t);
         }
@@ -142,16 +143,17 @@ public class AuthenticationAthenz implements Authentication, EncodedAuthenticati
         this.keyId = authParams.getOrDefault("keyId", "0");
         this.autoPrefetchEnabled = Boolean.valueOf(authParams.getOrDefault("autoPrefetchEnabled", "false"));
 
-        if (authParams.containsKey("athenzConfPath")) {
+        if (isNotBlank(authParams.get("athenzConfPath"))) {
             System.setProperty("athenz.athenz_conf", authParams.get("athenzConfPath"));
         }
-        if (authParams.containsKey("principalHeader")) {
+        if (isNotBlank(authParams.get("principalHeader"))) {
             System.setProperty("athenz.auth.principal.header", authParams.get("principalHeader"));
         }
-        if (authParams.containsKey("roleHeader")) {
-            System.setProperty("athenz.auth.role.header", authParams.get("roleHeader"));
+        if (isNotBlank(authParams.get("roleHeader"))) {
+            this.roleHeader = authParams.get("roleHeader");
+            System.setProperty("athenz.auth.role.header", this.roleHeader);
         }
-        if (authParams.containsKey("ztsUrl")) {
+        if (isNotBlank(authParams.get("ztsUrl"))) {
             this.ztsUrl = authParams.get("ztsUrl");
         }
     }
diff --git a/pulsar-client-auth-athenz/src/test/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenzTest.java b/pulsar-client-auth-athenz/src/test/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenzTest.java
index f6f6968..6323f17 100644
--- a/pulsar-client-auth-athenz/src/test/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenzTest.java
+++ b/pulsar-client-auth-athenz/src/test/java/org/apache/pulsar/client/impl/auth/AuthenticationAthenzTest.java
@@ -51,6 +51,38 @@ public class AuthenticationAthenzTest {
     private static final String TENANT_DOMAIN = "test_tenant";
     private static final String TENANT_SERVICE = "test_service";
 
+    class MockZTSClient extends ZTSClient {
+        public MockZTSClient(String ztsUrl) {
+            super(ztsUrl);
+        }
+
+        @Override
+        public RoleToken getRoleToken(String domainName, String roleName, Integer minExpiryTime, Integer maxExpiryTime,
+                boolean ignoreCache) {
+            List<String> roles = new ArrayList<String>() {
+                {
+                    add("test_role");
+                }
+            };
+            com.yahoo.athenz.auth.token.RoleToken roleToken = new com.yahoo.athenz.auth.token.RoleToken.Builder(
+                    "Z1", domainName, roles).principal(String.format("%s.%s", TENANT_DOMAIN, TENANT_SERVICE))
+                            .build();
+
+            try {
+                String ztsPrivateKey = new String(
+                        Files.readAllBytes(Paths.get("./src/test/resources/zts_private.pem")));
+                roleToken.sign(ztsPrivateKey);
+            } catch (IOException e) {
+                return null;
+            }
+
+            RoleToken token = new RoleToken();
+            token.setToken(roleToken.getSignedToken());
+
+            return token;
+        }
+    }
+
     @BeforeClass
     public void setup() throws Exception {
         String paramsStr = new String(Files.readAllBytes(Paths.get("./src/test/resources/authParams.json")));
@@ -59,36 +91,7 @@ public class AuthenticationAthenzTest {
         // Set mock ztsClient which returns fixed token instead of fetching from ZTS server
         Field field = auth.getClass().getDeclaredField("ztsClient");
         field.setAccessible(true);
-        ZTSClient mockZtsClient = new ZTSClient("dummy") {
-            @Override
-            public RoleToken getRoleToken(String domainName, String roleName, Integer minExpiryTime,
-                    Integer maxExpiryTime, boolean ignoreCache) {
-
-                List<String> roles = new ArrayList<String>() {
-                    {
-                        add("test_role");
-                    }
-                };
-                com.yahoo.athenz.auth.token.RoleToken roleToken = new com.yahoo.athenz.auth.token.RoleToken.Builder(
-                        "Z1", domainName, roles).principal(String.format("%s.%s", TENANT_DOMAIN, TENANT_SERVICE))
-                                .build();
-
-                try {
-                    String ztsPrivateKey = new String(
-                            Files.readAllBytes(Paths.get("./src/test/resources/zts_private.pem")));
-                    roleToken.sign(ztsPrivateKey);
-                } catch (IOException e) {
-                    return null;
-                }
-
-                RoleToken token = new RoleToken();
-                token.setToken(roleToken.getSignedToken());
-
-                return token;
-            }
-
-        };
-        field.set(auth, mockZtsClient);
+        field.set(auth, new MockZTSClient("dummy"));
     }
 
     @Test
@@ -194,4 +197,30 @@ public class AuthenticationAthenzTest {
         assertFalse((boolean) field.get(auth2));
         auth2.close();
     }
+
+    @Test
+    public void testRoleHeaderSetting() throws Exception {
+        assertEquals(auth.getAuthData().getHttpHeaders().iterator().next().getKey(), ZTSClient.getHeader());
+
+        Field field = auth.getClass().getDeclaredField("ztsClient");
+        field.setAccessible(true);
+
+        String paramsStr = new String(Files.readAllBytes(Paths.get("./src/test/resources/authParams.json")));
+        ObjectMapper jsonMapper = ObjectMapperFactory.create();
+        Map<String, String> authParamsMap = jsonMapper.readValue(paramsStr, new TypeReference<HashMap<String, String>>() { });
+
+        authParamsMap.put("roleHeader", "");
+        AuthenticationAthenz auth1 = new AuthenticationAthenz();
+        auth1.configure(jsonMapper.writeValueAsString(authParamsMap));
+        field.set(auth1, new MockZTSClient("dummy"));
+        assertEquals(auth1.getAuthData().getHttpHeaders().iterator().next().getKey(), ZTSClient.getHeader());
+        auth1.close();
+
+        authParamsMap.put("roleHeader", "Test-Role-Header");
+        AuthenticationAthenz auth2 = new AuthenticationAthenz();
+        auth2.configure(jsonMapper.writeValueAsString(authParamsMap));
+        field.set(auth2, new MockZTSClient("dummy"));
+        assertEquals(auth2.getAuthData().getHttpHeaders().iterator().next().getKey(), "Test-Role-Header");
+        auth2.close();
+    }
 }