You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by ma...@apache.org on 2022/05/25 06:52:35 UTC
[pulsar] branch branch-2.9 updated: Support handling single role and non-jwt-token in MultiRolesTokenAuthorizationProvider (#14857)
This is an automated email from the ASF dual-hosted git repository.
mattisonchao pushed a commit to branch branch-2.9
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/branch-2.9 by this push:
new a861242dc57 Support handling single role and non-jwt-token in MultiRolesTokenAuthorizationProvider (#14857)
a861242dc57 is described below
commit a861242dc57439be30def69d5a9a1821510ce7dd
Author: Zike Yang <zi...@apache.org>
AuthorDate: Sun May 8 23:08:45 2022 +0800
Support handling single role and non-jwt-token in MultiRolesTokenAuthorizationProvider (#14857)
### Motivation
Currently, `MultiRolesTokenAuthorizationProvider` doesn't support handling the single string type role. It will return the empty role in that case. This PR adds support for handling the string-type role. This PR also adds support for handling the non-jwt-token.
### Modifications
* Add support for handling the string-type role
* Add support for handling the non-jwt-token
### Verifying this change
This change is already covered by existing tests, such as *testMultiRolesAuthzWithSingleRole*.
(cherry picked from commit 8bf6785c0803d314465b2d9156df6ca5bbb3c644)
---
.../MultiRolesTokenAuthorizationProvider.java | 8 +-
.../MultiRolesTokenAuthorizationProviderTest.java | 101 +++++++++++++++++++++
2 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProvider.java b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProvider.java
index 8a91d7f6971..c508ccbd5b4 100644
--- a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProvider.java
+++ b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProvider.java
@@ -59,7 +59,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
// The token's claim that corresponds to the "role" string
static final String CONF_TOKEN_AUTH_CLAIM = "tokenAuthClaim";
- private JwtParser parser;
+ private final JwtParser parser;
private String roleClaim;
public MultiRolesTokenAuthorizationProvider() {
@@ -107,11 +107,15 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
return Collections.emptyList();
String[] splitToken = token.split("\\.");
+ if (splitToken.length < 2) {
+ log.warn("Unable to extract additional roles from JWT token");
+ return Collections.emptyList();
+ }
String unsignedToken = splitToken[0] + "." + splitToken[1] + ".";
Jwt<?, Claims> jwt = parser.parseClaimsJwt(unsignedToken);
try {
- Collections.singletonList(jwt.getBody().get(roleClaim, String.class));
+ return Collections.singletonList(jwt.getBody().get(roleClaim, String.class));
} catch (RequiredTypeException requiredTypeException) {
try {
List list = jwt.getBody().get(roleClaim, List.class);
diff --git a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProviderTest.java b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProviderTest.java
index edd0baa42ae..078e2aad07a 100644
--- a/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProviderTest.java
+++ b/pulsar-broker-common/src/test/java/org/apache/pulsar/broker/authorization/MultiRolesTokenAuthorizationProviderTest.java
@@ -18,10 +18,14 @@
*/
package org.apache.pulsar.broker.authorization;
+import static org.mockito.Mockito.mock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
+import java.util.Properties;
+import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
+import org.apache.pulsar.broker.resources.PulsarResources;
import org.junit.Assert;
import org.testng.annotations.Test;
@@ -96,4 +100,101 @@ public class MultiRolesTokenAuthorizationProviderTest {
Assert.assertFalse(provider.authorize(ads, role -> CompletableFuture.completedFuture(false)).get());
}
+
+ @Test
+ public void testMultiRolesAuthzWithSingleRole() throws Exception {
+ SecretKey secretKey = AuthTokenUtils.createSecretKey(SignatureAlgorithm.HS256);
+ String testRole = "test-role";
+ String token = Jwts.builder().claim("sub", testRole).signWith(secretKey).compact();
+
+ MultiRolesTokenAuthorizationProvider provider = new MultiRolesTokenAuthorizationProvider();
+
+ AuthenticationDataSource ads = new AuthenticationDataSource() {
+ @Override
+ public boolean hasDataFromHttp() {
+ return true;
+ }
+
+ @Override
+ public String getHttpHeader(String name) {
+ if (name.equals("Authorization")) {
+ return "Bearer " + token;
+ } else {
+ throw new IllegalArgumentException("Wrong HTTP header");
+ }
+ }
+ };
+
+ Assert.assertTrue(provider.authorize(ads, role -> {
+ if (role.equals(testRole)) {
+ return CompletableFuture.completedFuture(true);
+ }
+ return CompletableFuture.completedFuture(false);
+ }).get());
+ }
+
+ @Test
+ public void testMultiRolesNotFailNonJWT() throws Exception {
+ String token = "a-non-jwt-token";
+
+ MultiRolesTokenAuthorizationProvider provider = new MultiRolesTokenAuthorizationProvider();
+
+ AuthenticationDataSource ads = new AuthenticationDataSource() {
+ @Override
+ public boolean hasDataFromHttp() {
+ return true;
+ }
+
+ @Override
+ public String getHttpHeader(String name) {
+ if (name.equals("Authorization")) {
+ return "Bearer " + token;
+ } else {
+ throw new IllegalArgumentException("Wrong HTTP header");
+ }
+ }
+ };
+
+ Assert.assertFalse(provider.authorize(ads, role -> CompletableFuture.completedFuture(false)).get());
+ }
+
+ @Test
+ public void testMultiRolesAuthzWithCustomRolesClaims() throws Exception {
+ SecretKey secretKey = AuthTokenUtils.createSecretKey(SignatureAlgorithm.HS256);
+ String testRole = "test-role";
+ String customRolesClaims = "role";
+ String token = Jwts.builder().claim(customRolesClaims, new String[]{testRole}).signWith(secretKey).compact();
+
+ Properties properties = new Properties();
+ properties.setProperty("tokenSettingPrefix", "prefix_");
+ properties.setProperty("prefix_tokenAuthClaim", customRolesClaims);
+ ServiceConfiguration conf = new ServiceConfiguration();
+ conf.setProperties(properties);
+
+ MultiRolesTokenAuthorizationProvider provider = new MultiRolesTokenAuthorizationProvider();
+ provider.initialize(conf, mock(PulsarResources.class));
+
+ AuthenticationDataSource ads = new AuthenticationDataSource() {
+ @Override
+ public boolean hasDataFromHttp() {
+ return true;
+ }
+
+ @Override
+ public String getHttpHeader(String name) {
+ if (name.equals("Authorization")) {
+ return "Bearer " + token;
+ } else {
+ throw new IllegalArgumentException("Wrong HTTP header");
+ }
+ }
+ };
+
+ Assert.assertTrue(provider.authorize(ads, role -> {
+ if (role.equals(testRole)) {
+ return CompletableFuture.completedFuture(true);
+ }
+ return CompletableFuture.completedFuture(false);
+ }).get());
+ }
}