You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by eo...@apache.org on 2021/04/29 08:13:33 UTC

[pulsar] branch branch-2.7 updated: [WebSocket Client] WebSocket url token param value optimization (#10187)

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

eolivelli 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 16387e2  [WebSocket Client] WebSocket url token param value optimization (#10187)
16387e2 is described below

commit 16387e2f8dd35eefa3ce24b06a3d2d1138b9532a
Author: ran <ga...@126.com>
AuthorDate: Fri Apr 16 01:47:24 2021 +0800

    [WebSocket Client] WebSocket url token param value optimization (#10187)
    
    * Remove the `Bearer ` prefix requirement for the token param value of the WebSocket url.
    
    * add mock request test
    
    (cherry picked from commit 3e5fbcea4c424302cfd258d1238d2135eca2a555)
---
 .../WebSocketHttpServletRequestWrapper.java        |   8 +-
 .../WebSocketHttpServletRequestWrapperTest.java    |  85 ++++++++++++++
 pulsar-websocket/src/test/resources/my-public.key  | Bin 0 -> 294 bytes
 pulsar-websocket/src/test/resources/websocket.conf | 127 +++++++++++++++++++++
 4 files changed, 218 insertions(+), 2 deletions(-)

diff --git a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapper.java b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapper.java
index 29602a8..22cf7d1 100644
--- a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapper.java
+++ b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapper.java
@@ -22,13 +22,13 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 import org.eclipse.jetty.websocket.servlet.UpgradeHttpServletRequest;
 
-
 /**
  * WebSocket HttpServletRequest wrapper.
  */
 public class WebSocketHttpServletRequestWrapper extends HttpServletRequestWrapper {
 
     final static String HTTP_HEADER_NAME = "Authorization";
+    final static String HTTP_HEADER_VALUE_PREFIX = "Bearer ";
     final static String TOKEN = "token";
 
     public WebSocketHttpServletRequestWrapper(HttpServletRequest request) {
@@ -41,7 +41,11 @@ public class WebSocketHttpServletRequestWrapper extends HttpServletRequestWrappe
         // query param `token` to transport the auth token for the browser javascript WebSocket client.
         if (name.equals(HTTP_HEADER_NAME)
                 && !((UpgradeHttpServletRequest) this.getRequest()).getHeaders().containsKey(HTTP_HEADER_NAME)) {
-            return getRequest().getParameter(TOKEN);
+            String token = getRequest().getParameter(TOKEN);
+            if (token != null && !token.startsWith(HTTP_HEADER_VALUE_PREFIX)) {
+                return HTTP_HEADER_VALUE_PREFIX + token;
+            }
+            return token;
         }
         return super.getHeader(name);
     }
diff --git a/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapperTest.java b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapperTest.java
new file mode 100644
index 0000000..52bee3f
--- /dev/null
+++ b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/WebSocketHttpServletRequestWrapperTest.java
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pulsar.websocket;
+
+import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
+import org.apache.pulsar.websocket.service.WebSocketProxyConfiguration;
+import org.eclipse.jetty.websocket.servlet.UpgradeHttpServletRequest;
+import org.junit.Assert;
+import org.mockito.Mockito;
+import org.testng.annotations.Test;
+
+/**
+ * WebSocketHttpServletRequestWrapper test.
+ */
+public class WebSocketHttpServletRequestWrapperTest {
+
+    private final static String TOKEN = "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.U387jG"
+            + "-gmpEXNmTjbnnnk24jCXnfy7OTiQhhhOdXPgV2wEvZYr83KRSmH54wJQr4V2FCWIFb_6mBc_"
+            + "E2acpfpfBOTTzrtietfhd6wE5uOP2NXaLpy_kUDsE3ZQGKPEsn18cWQUw54GAzS1oRcG9TnoqSCSFFGabvo"
+            + "FTiOMHoBQ3ZHO3TqAGqlJlRF5ZXMkRtQ9vwbPC-mlwIfRrRIJfK5_ijPRkpgFSEvAwp0rX6roz08SyTj_"
+            + "d4UNT96nsEL6sRNTpZMQ0qNj2_LMKFnwF3O_xe43-Uen3TllkAzhNd9Z6qIxyJyFbaFyWAVgiAfoFWQD0v4EmV96ZzKZvv3CbGjw";
+    private final static String BEARER_TOKEN = WebSocketHttpServletRequestWrapper.HTTP_HEADER_VALUE_PREFIX + TOKEN;
+
+    @Test
+    public void testTokenParamWithBearerPrefix() {
+        UpgradeHttpServletRequest httpServletRequest = Mockito.mock(UpgradeHttpServletRequest.class);
+        Mockito.when(httpServletRequest.getParameter(WebSocketHttpServletRequestWrapper.TOKEN))
+                .thenReturn(BEARER_TOKEN);
+
+        WebSocketHttpServletRequestWrapper webSocketHttpServletRequestWrapper =
+                new WebSocketHttpServletRequestWrapper(httpServletRequest);
+        Assert.assertEquals(BEARER_TOKEN,
+                webSocketHttpServletRequestWrapper.getHeader(WebSocketHttpServletRequestWrapper.HTTP_HEADER_NAME));
+    }
+
+    @Test
+    public void testTokenParamWithOutBearerPrefix() {
+        UpgradeHttpServletRequest httpServletRequest = Mockito.mock(UpgradeHttpServletRequest.class);
+        Mockito.when(httpServletRequest.getParameter(WebSocketHttpServletRequestWrapper.TOKEN))
+                .thenReturn(TOKEN);
+
+        WebSocketHttpServletRequestWrapper webSocketHttpServletRequestWrapper =
+                new WebSocketHttpServletRequestWrapper(httpServletRequest);
+        Assert.assertEquals(BEARER_TOKEN,
+                webSocketHttpServletRequestWrapper.getHeader(WebSocketHttpServletRequestWrapper.HTTP_HEADER_NAME));
+    }
+
+    @Test
+    public void mockRequestTest() throws Exception {
+        WebSocketProxyConfiguration config = PulsarConfigurationLoader.create(
+                this.getClass().getClassLoader().getResource("websocket.conf").getFile(),
+                WebSocketProxyConfiguration.class);
+        String publicKeyPath = this.getClass().getClassLoader().getResource("my-public.key").getFile();
+        config.getProperties().setProperty("tokenPublicKey", publicKeyPath);
+        WebSocketService service = new WebSocketService(config);
+        service.start();
+
+        UpgradeHttpServletRequest httpServletRequest = Mockito.mock(UpgradeHttpServletRequest.class);
+        Mockito.when(httpServletRequest.getRemoteAddr()).thenReturn("localhost");
+        Mockito.when(httpServletRequest.getRemotePort()).thenReturn(8080);
+        Mockito.when(httpServletRequest.getParameter(WebSocketHttpServletRequestWrapper.TOKEN))
+                .thenReturn(TOKEN);
+        WebSocketHttpServletRequestWrapper webSocketHttpServletRequestWrapper =
+                new WebSocketHttpServletRequestWrapper(httpServletRequest);
+
+        Assert.assertEquals("test-user", service.getAuthenticationService().authenticateHttpRequest(webSocketHttpServletRequestWrapper));
+    }
+
+}
diff --git a/pulsar-websocket/src/test/resources/my-public.key b/pulsar-websocket/src/test/resources/my-public.key
new file mode 100644
index 0000000..43ca81e
Binary files /dev/null and b/pulsar-websocket/src/test/resources/my-public.key differ
diff --git a/pulsar-websocket/src/test/resources/websocket.conf b/pulsar-websocket/src/test/resources/websocket.conf
new file mode 100644
index 0000000..3d62926
--- /dev/null
+++ b/pulsar-websocket/src/test/resources/websocket.conf
@@ -0,0 +1,127 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+### --- Web Socket proxy settings --- ###
+
+# Configuration Store connection string
+configurationStoreServers=memory://127.0.0.1:2181
+
+# Zookeeper session timeout in milliseconds
+zooKeeperSessionTimeoutMillis=30000
+# ZooKeeper cache expiry time in seconds
+zooKeeperCacheExpirySeconds=300
+
+# Pulsar cluster url to connect to broker (optional if configurationStoreServers present)
+serviceUrl=localhost:6650
+serviceUrlTls=
+brokerServiceUrl=
+brokerServiceUrlTls=
+
+# Port to use to server HTTP request
+webServicePort=8080
+# Port to use to server HTTPS request
+webServicePortTls=
+
+# Path for the file used to determine the rotation status for the proxy-instance when responding
+# to service discovery health checks
+statusFilePath=
+
+# Hostname or IP address the service binds on, default is 0.0.0.0.
+bindAddress=0.0.0.0
+
+# Name of the pulsar cluster to connect to
+clusterName=standalone
+
+# Number of IO threads in Pulsar Client used in WebSocket proxy
+webSocketNumIoThreads=8
+
+# Number of threads to use in HTTP server. Default is Runtime.getRuntime().availableProcessors()
+numHttpServerThreads=
+
+# Number of connections per Broker in Pulsar Client used in WebSocket proxy
+webSocketConnectionsPerBroker=8
+
+# Time in milliseconds that idle WebSocket session times out
+webSocketSessionIdleTimeoutMillis=300000
+
+# The maximum size of a text message during parsing in WebSocket proxy
+webSocketMaxTextFrameSize=1048576
+
+### --- Authentication --- ###
+
+# Enable authentication
+authenticationEnabled=true
+
+# Autentication provider name list, which is comma separated list of class names
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
+
+# Enforce authorization
+authorizationEnabled=true
+
+# Authorization provider fully qualified class-name
+authorizationProvider=org.apache.pulsar.broker.authorization.PulsarAuthorizationProvider
+
+# Allow wildcard matching in authorization
+# (wildcard matching only applicable if wildcard-char:
+# * presents at first or last position eg: *.pulsar.service, pulsar.service.*)
+authorizationAllowWildcardsMatching=false
+
+# Role names that are treated as "super-user", meaning they will be able to do all admin
+# operations and publish/consume from all topics
+superUserRoles=test-user
+
+tokenPublicKey=./my-public.key
+
+# Authentication settings of the proxy itself. Used to connect to brokers
+brokerClientTlsEnabled=false
+brokerClientAuthenticationPlugin=
+brokerClientAuthenticationParameters=
+brokerClientTrustCertsFilePath=
+
+# When this parameter is not empty, unauthenticated users perform as anonymousUserRole
+anonymousUserRole=
+
+### --- TLS --- ###
+
+# Deprecated - use webServicePortTls and brokerClientTlsEnabled instead
+tlsEnabled=false
+
+# Accept untrusted TLS certificate from client
+tlsAllowInsecureConnection=false
+
+# Path for the TLS certificate file
+tlsCertificateFilePath=
+
+# Path for the TLS private key file
+tlsKeyFilePath=
+
+# Path for the trusted TLS certificate file
+tlsTrustCertsFilePath=
+
+# Specify whether Client certificates are required for TLS
+# Reject the Connection if the Client Certificate is not trusted.
+tlsRequireTrustedClientCertOnConnect=false
+
+# Tls cert refresh duration in seconds (set 0 to check on every new connection) 
+tlsCertRefreshCheckDurationSec=300
+
+### --- Deprecated config variables --- ###
+
+# Deprecated. Use configurationStoreServers
+globalZookeeperServers=