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=