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

jianghaiting pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/branch-2.7 by this push:
     new 3db2f7d88e2 [improve][authentication] Support for get token from HTTP 
params (#16892)
3db2f7d88e2 is described below

commit 3db2f7d88e2d46ad22830a1686658e7d27a74da0
Author: Zixuan Liu <[email protected]>
AuthorDate: Mon Aug 1 16:12:34 2022 +0800

    [improve][authentication] Support for get token from HTTP params (#16892)
    
    Signed-off-by: Zixuan Liu <[email protected]>
---
 .../authentication/AuthenticationDataHttps.java    |  3 +-
 .../AuthenticationProviderToken.java               | 46 ++++++++++-----
 .../AuthenticationProviderTokenTest.java           | 65 +++++++++++++++++++---
 3 files changed, 90 insertions(+), 24 deletions(-)

diff --git 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataHttps.java
 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataHttps.java
index 4e1d33b5ec5..0c262f5c620 100644
--- 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataHttps.java
+++ 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationDataHttps.java
@@ -19,7 +19,6 @@
 package org.apache.pulsar.broker.authentication;
 
 import java.security.cert.X509Certificate;
-
 import javax.servlet.http.HttpServletRequest;
 
 public class AuthenticationDataHttps extends AuthenticationDataHttp {
@@ -27,7 +26,7 @@ public class AuthenticationDataHttps extends 
AuthenticationDataHttp {
     protected final X509Certificate[] certificates;
 
     public AuthenticationDataHttps(HttpServletRequest request) {
-        super(request);
+        super(new 
AuthenticationProviderToken.HttpServletRequestWrapper(request));
         certificates = (X509Certificate[]) 
request.getAttribute("javax.servlet.request.X509Certificate");
     }
 
diff --git 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderToken.java
 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderToken.java
index 80b9978fc43..d5e99403e9f 100644
--- 
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderToken.java
+++ 
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authentication/AuthenticationProviderToken.java
@@ -19,33 +19,30 @@
 package org.apache.pulsar.broker.authentication;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
-
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.Jwt;
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.JwtParser;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.SignatureException;
+import io.prometheus.client.Counter;
+import io.prometheus.client.Histogram;
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.security.Key;
-
 import java.util.Date;
 import java.util.List;
 import javax.naming.AuthenticationException;
 import javax.net.ssl.SSLSession;
-
-import io.jsonwebtoken.ExpiredJwtException;
-import io.jsonwebtoken.JwtParser;
-import io.prometheus.client.Counter;
-import io.prometheus.client.Histogram;
+import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.pulsar.broker.ServiceConfiguration;
 import org.apache.pulsar.broker.authentication.metrics.AuthenticationMetrics;
 import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
 import org.apache.pulsar.common.api.AuthData;
 
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwt;
-import io.jsonwebtoken.JwtException;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import io.jsonwebtoken.security.SignatureException;
-
 public class AuthenticationProviderToken implements AuthenticationProvider {
 
     final static String HTTP_HEADER_NAME = "Authorization";
@@ -351,4 +348,25 @@ public class AuthenticationProviderToken implements 
AuthenticationProvider {
             return expiration < System.currentTimeMillis();
         }
     }
+    public static final class HttpServletRequestWrapper extends 
javax.servlet.http.HttpServletRequestWrapper {
+        private final HttpServletRequest request;
+
+        public HttpServletRequestWrapper(HttpServletRequest request) {
+            super(request);
+            this.request = request;
+        }
+
+        @Override
+        public String getHeader(String name) {
+            // The browser javascript WebSocket client couldn't add the auth 
param to the request header, use the
+            // query param `token` to transport the auth token for the browser 
javascript WebSocket client.
+            if (name.equals(HTTP_HEADER_NAME) && 
request.getHeader(HTTP_HEADER_NAME) == null) {
+                String token = request.getParameter(TOKEN);
+                if (token != null) {
+                    return !token.startsWith(HTTP_HEADER_VALUE_PREFIX) ? 
HTTP_HEADER_VALUE_PREFIX + token : token;
+                }
+            }
+            return super.getHeader(name);
+        }
+    }
 }
diff --git 
a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTokenTest.java
 
b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTokenTest.java
index 5a2e1c4ea48..1e328050dac 100644
--- 
a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTokenTest.java
+++ 
b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authentication/AuthenticationProviderTokenTest.java
@@ -18,13 +18,13 @@
  */
 package org.apache.pulsar.broker.authentication;
 
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
-
 import com.google.common.collect.Lists;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwt;
@@ -33,25 +33,23 @@ import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import io.jsonwebtoken.io.Decoders;
 import io.jsonwebtoken.security.Keys;
-import java.security.Key;
-import java.util.List;
-import lombok.Cleanup;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.security.Key;
 import java.security.KeyPair;
 import java.security.PrivateKey;
 import java.sql.Date;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.concurrent.TimeUnit;
-
 import javax.crypto.SecretKey;
 import javax.naming.AuthenticationException;
-
+import javax.servlet.http.HttpServletRequest;
+import lombok.Cleanup;
 import org.apache.pulsar.broker.ServiceConfiguration;
 import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
 import org.apache.pulsar.common.api.AuthData;
@@ -800,4 +798,55 @@ public class AuthenticationProviderTokenTest {
         assertEquals(subject, SUBJECT);
         provider.close();
     }
+
+    @Test
+    public void testTokenFromHttpParams() throws Exception {
+        SecretKey secretKey = 
AuthTokenUtils.createSecretKey(SignatureAlgorithm.HS256);
+
+        @Cleanup
+        AuthenticationProviderToken provider = new 
AuthenticationProviderToken();
+
+        Properties properties = new Properties();
+        
properties.setProperty(AuthenticationProviderToken.CONF_TOKEN_SECRET_KEY,
+                AuthTokenUtils.encodeKeyBase64(secretKey));
+
+        ServiceConfiguration conf = new ServiceConfiguration();
+        conf.setProperties(properties);
+        provider.initialize(conf);
+
+        String token = AuthTokenUtils.createToken(secretKey, SUBJECT, 
Optional.empty());
+        HttpServletRequest servletRequest = mock(HttpServletRequest.class);
+        doReturn(token).when(servletRequest).getParameter("token");
+        doReturn(null).when(servletRequest).getHeader("Authorization");
+        doReturn("127.0.0.1").when(servletRequest).getRemoteAddr();
+        doReturn(0).when(servletRequest).getRemotePort();
+
+        AuthenticationDataHttps authenticationDataHttps = new 
AuthenticationDataHttps(servletRequest);
+        provider.authenticate(authenticationDataHttps);
+    }
+
+    @Test
+    public void testTokenFromHttpHeaders() throws Exception {
+        SecretKey secretKey = 
AuthTokenUtils.createSecretKey(SignatureAlgorithm.HS256);
+
+        @Cleanup
+        AuthenticationProviderToken provider = new 
AuthenticationProviderToken();
+
+        Properties properties = new Properties();
+        
properties.setProperty(AuthenticationProviderToken.CONF_TOKEN_SECRET_KEY,
+                AuthTokenUtils.encodeKeyBase64(secretKey));
+
+        ServiceConfiguration conf = new ServiceConfiguration();
+        conf.setProperties(properties);
+        provider.initialize(conf);
+
+        String token = AuthTokenUtils.createToken(secretKey, SUBJECT, 
Optional.empty());
+        HttpServletRequest servletRequest = mock(HttpServletRequest.class);
+        doReturn("Bearer " + 
token).when(servletRequest).getHeader("Authorization");
+        doReturn("127.0.0.1").when(servletRequest).getRemoteAddr();
+        doReturn(0).when(servletRequest).getRemotePort();
+
+        AuthenticationDataHttps authenticationDataHttps = new 
AuthenticationDataHttps(servletRequest);
+        provider.authenticate(authenticationDataHttps);
+    }
 }

Reply via email to