You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by ti...@apache.org on 2023/10/10 15:45:17 UTC
[pulsar] branch master updated: [fix][sec] Fix MultiRoles token provider when using anonymous clients (#21338)
This is an automated email from the ASF dual-hosted git repository.
tison 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 84204207c19 [fix][sec] Fix MultiRoles token provider when using anonymous clients (#21338)
84204207c19 is described below
commit 84204207c19cad0bf9986088af2bbd954b85288b
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Tue Oct 10 23:45:10 2023 +0800
[fix][sec] Fix MultiRoles token provider when using anonymous clients (#21338)
Co-authored-by: Lari Hotari <lh...@apache.org>
---
.../MultiRolesTokenAuthorizationProvider.java | 45 +++++++++++++---------
.../MultiRolesTokenAuthorizationProviderTest.java | 31 +++++++++++----
2 files changed, 50 insertions(+), 26 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 db5f4f18e8c..6376b60217f 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
@@ -97,7 +97,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
if (role != null && superUserRoles.contains(role)) {
return CompletableFuture.completedFuture(true);
}
- Set<String> roles = getRoles(authenticationData);
+ Set<String> roles = getRoles(role, authenticationData);
if (roles.isEmpty()) {
return CompletableFuture.completedFuture(false);
}
@@ -112,7 +112,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
if (isSuperUser) {
return CompletableFuture.completedFuture(true);
}
- Set<String> roles = getRoles(authData);
+ Set<String> roles = getRoles(role, authData);
if (roles.isEmpty()) {
return CompletableFuture.completedFuture(false);
}
@@ -143,7 +143,11 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
});
}
- private Set<String> getRoles(AuthenticationDataSource authData) {
+ private Set<String> getRoles(String role, AuthenticationDataSource authData) {
+ if (authData == null) {
+ return Collections.singleton(role);
+ }
+
String token = null;
if (authData.hasDataFromCommand()) {
@@ -192,9 +196,9 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
return Collections.emptySet();
}
- public CompletableFuture<Boolean> authorize(AuthenticationDataSource authenticationData, Function<String,
- CompletableFuture<Boolean>> authorizeFunc) {
- Set<String> roles = getRoles(authenticationData);
+ public CompletableFuture<Boolean> authorize(String role, AuthenticationDataSource authenticationData,
+ Function<String, CompletableFuture<Boolean>> authorizeFunc) {
+ Set<String> roles = getRoles(role, authenticationData);
if (roles.isEmpty()) {
return CompletableFuture.completedFuture(false);
}
@@ -212,7 +216,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
@Override
public CompletableFuture<Boolean> canProduceAsync(TopicName topicName, String role,
AuthenticationDataSource authenticationData) {
- return authorize(authenticationData, r -> super.canProduceAsync(topicName, r, authenticationData));
+ return authorize(role, authenticationData, r -> super.canProduceAsync(topicName, r, authenticationData));
}
/**
@@ -227,7 +231,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
public CompletableFuture<Boolean> canConsumeAsync(TopicName topicName, String role,
AuthenticationDataSource authenticationData,
String subscription) {
- return authorize(authenticationData, r -> super.canConsumeAsync(topicName, r, authenticationData,
+ return authorize(role, authenticationData, r -> super.canConsumeAsync(topicName, r, authenticationData,
subscription));
}
@@ -244,25 +248,27 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
@Override
public CompletableFuture<Boolean> canLookupAsync(TopicName topicName, String role,
AuthenticationDataSource authenticationData) {
- return authorize(authenticationData, r -> super.canLookupAsync(topicName, r, authenticationData));
+ return authorize(role, authenticationData, r -> super.canLookupAsync(topicName, r, authenticationData));
}
@Override
public CompletableFuture<Boolean> allowFunctionOpsAsync(NamespaceName namespaceName, String role,
AuthenticationDataSource authenticationData) {
- return authorize(authenticationData, r -> super.allowFunctionOpsAsync(namespaceName, r, authenticationData));
+ return authorize(role, authenticationData,
+ r -> super.allowFunctionOpsAsync(namespaceName, r, authenticationData));
}
@Override
public CompletableFuture<Boolean> allowSourceOpsAsync(NamespaceName namespaceName, String role,
AuthenticationDataSource authenticationData) {
- return authorize(authenticationData, r -> super.allowSourceOpsAsync(namespaceName, r, authenticationData));
+ return authorize(role, authenticationData,
+ r -> super.allowSourceOpsAsync(namespaceName, r, authenticationData));
}
@Override
public CompletableFuture<Boolean> allowSinkOpsAsync(NamespaceName namespaceName, String role,
AuthenticationDataSource authenticationData) {
- return authorize(authenticationData, r -> super.allowSinkOpsAsync(namespaceName, r, authenticationData));
+ return authorize(role, authenticationData, r -> super.allowSinkOpsAsync(namespaceName, r, authenticationData));
}
@Override
@@ -270,7 +276,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
String role,
TenantOperation operation,
AuthenticationDataSource authData) {
- return authorize(authData, r -> super.allowTenantOperationAsync(tenantName, r, operation, authData));
+ return authorize(role, authData, r -> super.allowTenantOperationAsync(tenantName, r, operation, authData));
}
@Override
@@ -278,7 +284,8 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
String role,
NamespaceOperation operation,
AuthenticationDataSource authData) {
- return authorize(authData, r -> super.allowNamespaceOperationAsync(namespaceName, r, operation, authData));
+ return authorize(role, authData,
+ r -> super.allowNamespaceOperationAsync(namespaceName, r, operation, authData));
}
@Override
@@ -287,8 +294,8 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
PolicyOperation operation,
String role,
AuthenticationDataSource authData) {
- return authorize(authData, r -> super.allowNamespacePolicyOperationAsync(namespaceName, policy, operation, r,
- authData));
+ return authorize(role, authData,
+ r -> super.allowNamespacePolicyOperationAsync(namespaceName, policy, operation, r, authData));
}
@Override
@@ -296,7 +303,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
String role,
TopicOperation operation,
AuthenticationDataSource authData) {
- return authorize(authData, r -> super.allowTopicOperationAsync(topicName, r, operation, authData));
+ return authorize(role, authData, r -> super.allowTopicOperationAsync(topicName, r, operation, authData));
}
@Override
@@ -305,7 +312,7 @@ public class MultiRolesTokenAuthorizationProvider extends PulsarAuthorizationPro
PolicyName policyName,
PolicyOperation policyOperation,
AuthenticationDataSource authData) {
- return authorize(authData, r -> super.allowTopicPolicyOperationAsync(topicName, r, policyName, policyOperation,
- authData));
+ return authorize(role, authData,
+ r -> super.allowTopicPolicyOperationAsync(topicName, r, policyName, policyOperation, authData));
}
}
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 f0a857bdd69..4b67f52075c 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
@@ -24,6 +24,8 @@ import static org.testng.Assert.assertTrue;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Properties;
+import java.util.function.Function;
+import lombok.Cleanup;
import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.authentication.AuthenticationDataSource;
import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
@@ -61,18 +63,18 @@ public class MultiRolesTokenAuthorizationProviderTest {
}
};
- assertTrue(provider.authorize(ads, role -> {
+ assertTrue(provider.authorize("test", ads, role -> {
if (role.equals(userB)) {
return CompletableFuture.completedFuture(true); // only userB has permission
}
return CompletableFuture.completedFuture(false);
}).get());
- assertTrue(provider.authorize(ads, role -> {
+ assertTrue(provider.authorize("test", ads, role -> {
return CompletableFuture.completedFuture(true); // all users has permission
}).get());
- assertFalse(provider.authorize(ads, role -> {
+ assertFalse(provider.authorize("test", ads, role -> {
return CompletableFuture.completedFuture(false); // all users has no permission
}).get());
}
@@ -100,7 +102,7 @@ public class MultiRolesTokenAuthorizationProviderTest {
}
};
- assertFalse(provider.authorize(ads, role -> CompletableFuture.completedFuture(false)).get());
+ assertFalse(provider.authorize("test", ads, role -> CompletableFuture.completedFuture(false)).get());
}
@Test
@@ -127,7 +129,7 @@ public class MultiRolesTokenAuthorizationProviderTest {
}
};
- assertTrue(provider.authorize(ads, role -> {
+ assertTrue(provider.authorize("test", ads, role -> {
if (role.equals(testRole)) {
return CompletableFuture.completedFuture(true);
}
@@ -135,6 +137,21 @@ public class MultiRolesTokenAuthorizationProviderTest {
}).get());
}
+ @Test
+ public void testMultiRolesAuthzWithAnonymousUser() throws Exception {
+ @Cleanup
+ MultiRolesTokenAuthorizationProvider provider = new MultiRolesTokenAuthorizationProvider();
+
+ Function<String, CompletableFuture<Boolean>> authorizeFunc = (String role) -> {
+ if (role.equals("test-role")) {
+ return CompletableFuture.completedFuture(true);
+ }
+ return CompletableFuture.completedFuture(false);
+ };
+ assertTrue(provider.authorize("test-role", null, authorizeFunc).get());
+ assertFalse(provider.authorize("test-role-x", null, authorizeFunc).get());
+ }
+
@Test
public void testMultiRolesNotFailNonJWT() throws Exception {
String token = "a-non-jwt-token";
@@ -157,7 +174,7 @@ public class MultiRolesTokenAuthorizationProviderTest {
}
};
- assertFalse(provider.authorize(ads, role -> CompletableFuture.completedFuture(false)).get());
+ assertFalse(provider.authorize("test", ads, role -> CompletableFuture.completedFuture(false)).get());
}
@Test
@@ -192,7 +209,7 @@ public class MultiRolesTokenAuthorizationProviderTest {
}
};
- assertTrue(provider.authorize(ads, role -> {
+ assertTrue(provider.authorize("test", ads, role -> {
if (role.equals(testRole)) {
return CompletableFuture.completedFuture(true);
}