This is an automated email from the ASF dual-hosted git repository.
technoboy 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 822f89752b4 [improve][authentication] Support for get token from HTTP
params (#16650)
822f89752b4 is described below
commit 822f89752b48840f658280d1c25ae8af37214190
Author: Zixuan Liu <[email protected]>
AuthorDate: Tue Jul 26 10:36:59 2022 +0800
[improve][authentication] Support for get token from HTTP params (#16650)
---
.../AuthenticationProviderToken.java | 24 +++++++-
.../AuthenticationProviderTokenTest.java | 68 +++++++++++++++++++---
2 files changed, 82 insertions(+), 10 deletions(-)
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 5c6d17a1d77..9cc220aa8c7 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
@@ -168,7 +168,7 @@ public class AuthenticationProviderToken implements
AuthenticationProvider {
@Override
public AuthenticationState newHttpAuthState(HttpServletRequest request)
throws AuthenticationException {
- return new TokenAuthenticationState(this, request);
+ return new TokenAuthenticationState(this, new
HttpServletRequestWrapper(request));
}
public static String getToken(AuthenticationDataSource authData) throws
AuthenticationException {
@@ -387,4 +387,26 @@ public class AuthenticationProviderToken implements
AuthenticationProvider {
return expiration < System.currentTimeMillis();
}
}
+
+ private 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 0d293549156..c7ab2781300 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
@@ -19,12 +19,13 @@
package org.apache.pulsar.broker.authentication;
import static org.mockito.ArgumentMatchers.anyString;
+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.assertTrue;
import static org.testng.Assert.fail;
-
import com.google.common.collect.Lists;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
@@ -33,26 +34,24 @@ 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.Arrays;
-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.Arrays;
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;
@@ -837,7 +836,7 @@ public class AuthenticationProviderTokenTest {
ServiceConfiguration conf = new ServiceConfiguration();
conf.setProperties(properties);
- ServiceConfiguration mockConf =
Mockito.mock(ServiceConfiguration.class);
+ ServiceConfiguration mockConf = mock(ServiceConfiguration.class);
String prefix = "test";
Mockito.when(mockConf.getProperty(anyString()))
@@ -864,6 +863,57 @@ public class AuthenticationProviderTokenTest {
.getProperty(prefix +
AuthenticationProviderToken.CONF_TOKEN_AUDIENCE);
}
+ @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();
+
+ AuthenticationState authState =
provider.newHttpAuthState(servletRequest);
+ provider.authenticate(authState.getAuthDataSource());
+ }
+
+ @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();
+
+ AuthenticationState authState =
provider.newHttpAuthState(servletRequest);
+ provider.authenticate(authState.getAuthDataSource());
+ }
+
private static String createTokenWithAudience(Key signingKey, String
audienceClaim, List<String> audience) {
JwtBuilder builder = Jwts.builder()
.setSubject(SUBJECT)