This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new 1d6de4c661 [#9254,#9168] improvement(authz): Optimize metadata
authorization in the list metalake and list role. (#9255)
1d6de4c661 is described below
commit 1d6de4c661dc2e64351b0886945bf7a3c391c227
Author: yangyang zhong <[email protected]>
AuthorDate: Thu Nov 27 17:41:31 2025 +0800
[#9254,#9168] improvement(authz): Optimize metadata authorization in the
list metalake and list role. (#9255)
### What changes were proposed in this pull request?
Optimize metadata authorization in the list metalake and list role.
### Why are the changes needed?
Fix: #9254 #9168
### Does this PR introduce _any_ user-facing change?
None
### How was this patch tested?
Existing test case in
org.apache.gravitino.client.integration.test.authorization.MetalakeAuthorizationIT
Existing test case in
org.apache.gravitino.client.integration.test.authorization.RoleAuthorizationIT
---
.../server/authorization/MetadataAuthzHelper.java | 88 +++++++++++-----------
.../gravitino/server/web/filter/ParameterUtil.java | 2 +-
.../server/web/rest/MetalakeOperations.java | 17 +----
.../gravitino/server/web/rest/RoleOperations.java | 23 ++----
4 files changed, 51 insertions(+), 79 deletions(-)
diff --git
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
index fa96fa236a..f315613698 100644
---
a/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
+++
b/server-common/src/main/java/org/apache/gravitino/server/authorization/MetadataAuthzHelper.java
@@ -33,6 +33,7 @@ import org.apache.gravitino.Config;
import org.apache.gravitino.Configs;
import org.apache.gravitino.Entity;
import org.apache.gravitino.GravitinoEnv;
+import org.apache.gravitino.Metalake;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.authorization.AuthorizationRequestContext;
import org.apache.gravitino.authorization.GravitinoAuthorizer;
@@ -88,6 +89,25 @@ public class MetadataAuthzHelper {
.toArray(NameIdentifier[]::new);
}
+ public static Metalake[] filterMetalakes(Metalake[] metalakes, String
expression) {
+ if (!enableAuthorization()) {
+ return metalakes;
+ }
+ checkExecutor();
+ AuthorizationRequestContext authorizationRequestContext = new
AuthorizationRequestContext();
+ return doFilter(
+ expression,
+ metalakes,
+ GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer(),
+ authorizationRequestContext,
+ metalake -> {
+ String metalakeName = metalake.name();
+ return splitMetadataNames(
+ metalakeName,
+ Entity.EntityType.METALAKE,
+ NameIdentifierUtil.ofMetalake(metalakeName));
+ });
+ }
/**
* Call {@link AuthorizationExpressionEvaluator} to filter the metadata list
*
@@ -102,41 +122,7 @@ public class MetadataAuthzHelper {
String expression,
Entity.EntityType entityType,
NameIdentifier[] nameIdentifiers) {
- if (!enableAuthorization()) {
- return nameIdentifiers;
- }
- checkExecutor();
- AuthorizationRequestContext authorizationRequestContext = new
AuthorizationRequestContext();
- List<CompletableFuture<NameIdentifier>> futures = new ArrayList<>();
- for (NameIdentifier nameIdentifier : nameIdentifiers) {
- Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
- futures.add(
- CompletableFuture.supplyAsync(
- () -> {
- try {
- return PrincipalUtils.doAs(
- currentPrincipal,
- () -> {
- Map<Entity.EntityType, NameIdentifier>
nameIdentifierMap =
- spiltMetadataNames(metalake, entityType,
nameIdentifier);
- AuthorizationExpressionEvaluator
authorizationExpressionEvaluator =
- new AuthorizationExpressionEvaluator(expression);
- return authorizationExpressionEvaluator.evaluate(
- nameIdentifierMap, authorizationRequestContext)
- ? nameIdentifier
- : null;
- });
- } catch (Exception e) {
- LOG.error("GravitinoAuthorize error:{}", e.getMessage(), e);
- return null;
- }
- },
- executor));
- }
- return futures.stream()
- .map(CompletableFuture::join)
- .filter(Objects::nonNull)
- .toArray(NameIdentifier[]::new);
+ return filterByExpression(metalake, expression, entityType,
nameIdentifiers, e -> e);
}
/**
@@ -155,7 +141,7 @@ public class MetadataAuthzHelper {
String metalake = NameIdentifierUtil.getMetalake(identifier);
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap =
- spiltMetadataNames(metalake, entityType, identifier);
+ splitMetadataNames(metalake, entityType, identifier);
AuthorizationExpressionEvaluator authorizationExpressionEvaluator =
new AuthorizationExpressionEvaluator(expression);
return authorizationExpressionEvaluator.evaluate(
@@ -181,9 +167,8 @@ public class MetadataAuthzHelper {
Function<E, NameIdentifier> toNameIdentifier) {
GravitinoAuthorizer authorizer =
GravitinoAuthorizerProvider.getInstance().getGravitinoAuthorizer();
- Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
return filterByExpression(
- metalake, expression, entityType, entities, toNameIdentifier,
currentPrincipal, authorizer);
+ metalake, expression, entityType, entities, toNameIdentifier,
authorizer);
}
/**
@@ -195,7 +180,6 @@ public class MetadataAuthzHelper {
* @param entityType entity type
* @param entities metadata entities
* @param toNameIdentifier function to convert entity to NameIdentifier
- * @param currentPrincipal current principal
* @param authorizer authorizer to filter metadata
* @return Filtered Metadata Entity
* @param <E> Entity class
@@ -206,13 +190,30 @@ public class MetadataAuthzHelper {
Entity.EntityType entityType,
E[] entities,
Function<E, NameIdentifier> toNameIdentifier,
- Principal currentPrincipal,
GravitinoAuthorizer authorizer) {
if (!enableAuthorization()) {
return entities;
}
checkExecutor();
AuthorizationRequestContext authorizationRequestContext = new
AuthorizationRequestContext();
+ return doFilter(
+ expression,
+ entities,
+ authorizer,
+ authorizationRequestContext,
+ (entity) -> {
+ NameIdentifier nameIdentifier = toNameIdentifier.apply(entity);
+ return splitMetadataNames(metalake, entityType, nameIdentifier);
+ });
+ }
+
+ private static <E> E[] doFilter(
+ String expression,
+ E[] entities,
+ GravitinoAuthorizer authorizer,
+ AuthorizationRequestContext authorizationRequestContext,
+ Function<E, Map<Entity.EntityType, NameIdentifier>>
extractMetadataNamesMap) {
+ Principal currentPrincipal = PrincipalUtils.getCurrentPrincipal();
List<CompletableFuture<E>> futures = new ArrayList<>();
for (E entity : entities) {
futures.add(
@@ -224,11 +225,8 @@ public class MetadataAuthzHelper {
() -> {
AuthorizationExpressionEvaluator
authorizationExpressionEvaluator =
new AuthorizationExpressionEvaluator(expression,
authorizer);
- NameIdentifier nameIdentifier =
toNameIdentifier.apply(entity);
- Map<Entity.EntityType, NameIdentifier>
nameIdentifierMap =
- spiltMetadataNames(metalake, entityType,
nameIdentifier);
return authorizationExpressionEvaluator.evaluate(
- nameIdentifierMap, authorizationRequestContext)
+ extractMetadataNamesMap.apply(entity),
authorizationRequestContext)
? entity
: null;
});
@@ -255,7 +253,7 @@ public class MetadataAuthzHelper {
* @param nameIdentifier metadata name
* @return A map containing the metadata object and all its parent objects,
keyed by their types
*/
- public static Map<Entity.EntityType, NameIdentifier> spiltMetadataNames(
+ public static Map<Entity.EntityType, NameIdentifier> splitMetadataNames(
String metalake, Entity.EntityType entityType, NameIdentifier
nameIdentifier) {
Map<Entity.EntityType, NameIdentifier> nameIdentifierMap = new HashMap<>();
nameIdentifierMap.put(Entity.EntityType.METALAKE,
NameIdentifierUtil.ofMetalake(metalake));
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/filter/ParameterUtil.java
b/server/src/main/java/org/apache/gravitino/server/web/filter/ParameterUtil.java
index 8658374d36..ac4f548026 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/filter/ParameterUtil.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/filter/ParameterUtil.java
@@ -171,7 +171,7 @@ public class ParameterUtil {
NameIdentifier nameIdentifier =
MetadataObjectUtil.toEntityIdent(metalake,
MetadataObjects.parse(fullName, type));
nameIdentifierMap.putAll(
- MetadataAuthzHelper.spiltMetadataNames(
+ MetadataAuthzHelper.splitMetadataNames(
metalake, MetadataObjectUtil.toEntityType(type),
nameIdentifier));
}
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
index 0d0895b11b..5c94b5517f 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/MetalakeOperations.java
@@ -89,22 +89,7 @@ public class MetalakeOperations {
httpRequest,
() -> {
Metalake[] metalakes = metalakeDispatcher.listMetalakes();
- metalakes =
- Arrays.stream(metalakes)
- .filter(
- metalake -> {
- NameIdentifier[] nameIdentifiers =
- new NameIdentifier[]
{NameIdentifierUtil.ofMetalake(metalake.name())};
- return MetadataAuthzHelper.filterByExpression(
- metalake.name(),
- "METALAKE_USER",
- Entity.EntityType.METALAKE,
- nameIdentifiers)
- .length
- > 0;
- })
- .toList()
- .toArray(new Metalake[0]);
+ metalakes = MetadataAuthzHelper.filterMetalakes(metalakes,
"METALAKE_USER");
MetalakeDTO[] metalakeDTOs =
Arrays.stream(metalakes).map(DTOConverters::toDTO).toArray(MetalakeDTO[]::new);
Response response = Utils.ok(new
MetalakeListResponse(metalakeDTOs));
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/rest/RoleOperations.java
b/server/src/main/java/org/apache/gravitino/server/web/rest/RoleOperations.java
index 49f640b988..844ed4ece3 100644
---
a/server/src/main/java/org/apache/gravitino/server/web/rest/RoleOperations.java
+++
b/server/src/main/java/org/apache/gravitino/server/web/rest/RoleOperations.java
@@ -38,7 +38,6 @@ import org.apache.gravitino.Entity;
import org.apache.gravitino.GravitinoEnv;
import org.apache.gravitino.MetadataObject;
import org.apache.gravitino.MetadataObjects;
-import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.authorization.AccessControlDispatcher;
import org.apache.gravitino.authorization.AuthorizationUtils;
import org.apache.gravitino.authorization.Privilege;
@@ -92,22 +91,12 @@ public class RoleOperations {
() -> {
String[] names = accessControlManager.listRoleNames(metalake);
names =
- Arrays.stream(names)
- .filter(
- role -> {
- NameIdentifier[] nameIdentifiers =
- new NameIdentifier[]
{NameIdentifierUtil.ofRole(metalake, role)};
- return MetadataAuthzHelper.filterByExpression(
- metalake,
- AuthorizationExpressionConstants
- .loadRoleAuthorizationExpression,
- Entity.EntityType.ROLE,
- nameIdentifiers)
- .length
- > 0;
- })
- .collect(Collectors.toList())
- .toArray(new String[0]);
+ MetadataAuthzHelper.filterByExpression(
+ metalake,
+
AuthorizationExpressionConstants.loadRoleAuthorizationExpression,
+ Entity.EntityType.ROLE,
+ names,
+ roleName -> NameIdentifierUtil.ofRole(metalake, roleName));
return Utils.ok(new NameListResponse(names));
});
} catch (Exception e) {