This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 4817d1b8e RANGER-5505: update RangerEmbeddedAuthorizer to support
caller provided audit handler (#864)
4817d1b8e is described below
commit 4817d1b8eb1facd877a5298cd9eb5509894bcde8
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Tue Mar 3 22:25:12 2026 -0800
RANGER-5505: update RangerEmbeddedAuthorizer to support caller provided
audit handler (#864)
---
.../authz/embedded/RangerAuthzAuditHandler.java | 13 +--
.../ranger/authz/embedded/RangerAuthzConfig.java | 9 +-
.../authz/embedded/RangerEmbeddedAuthorizer.java | 97 ++++++++++++++--------
.../authz/embedded/TestEmbeddedAuthorizer.java | 71 ++++++++++++++--
.../authz/embedded/TestRangerAuthzConfig.java | 6 ++
.../src/test/resources/test_hive/tests_authz.json | 7 +-
.../test/resources/test_s3/tests_multi_authz.json | 7 +-
7 files changed, 159 insertions(+), 51 deletions(-)
diff --git
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzAuditHandler.java
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzAuditHandler.java
index a16c5ede6..f9eab585a 100644
---
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzAuditHandler.java
+++
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzAuditHandler.java
@@ -22,20 +22,19 @@
import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
-import org.apache.ranger.plugin.service.RangerBasePlugin;
import java.util.ArrayList;
import java.util.Collection;
public class RangerAuthzAuditHandler extends RangerDefaultAuditHandler
implements AutoCloseable {
- private final RangerBasePlugin plugin;
+ private final String appType;
private final Collection<AuthzAuditEvent> auditEvents = new ArrayList<>();
private boolean deniedExists;
- public RangerAuthzAuditHandler(RangerBasePlugin plugin) {
+ public RangerAuthzAuditHandler(String appType) {
super();
- this.plugin = plugin;
+ this.appType = appType;
}
@Override
@@ -44,7 +43,7 @@ public void processResult(RangerAccessResult result) {
AuthzAuditEvent auditEvent = getAuthzEvents(result);
if (auditEvent != null) {
- auditEvent.setAgentId(plugin.getAppId());
+ auditEvent.setAgentId(appType);
if (result.getIsAccessDetermined() && !result.getIsAllowed()) {
deniedExists = true;
@@ -66,4 +65,8 @@ public void processResults(Collection<RangerAccessResult>
results) {
public void close() {
auditEvents.forEach(super::logAuthzAudit);
}
+
+ protected Collection<AuthzAuditEvent> getAuditEvents() {
+ return auditEvents;
+ }
}
diff --git
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzConfig.java
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzConfig.java
index 71ba854a8..39271dbc8 100644
---
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzConfig.java
+++
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerAuthzConfig.java
@@ -24,7 +24,8 @@
import java.util.Properties;
public class RangerAuthzConfig {
- public static final String PROP_PREFIX_INIT_SERVICES =
"ranger.authz.init.services";
+ public static final String PROP_APP_TYPE =
"ranger.authz.app.type";
+ public static final String PROP_INIT_SERVICES =
"ranger.authz.init.services";
public static final String PROP_PREFIX_DEFAULT =
"ranger.authz.default.";
public static final String PROP_PREFIX_AUDIT =
"ranger.authz.audit.";
public static final String PROP_PREFIX_SERVICE =
"ranger.authz.service.";
@@ -37,7 +38,7 @@ public RangerAuthzConfig(Properties properties) {
}
public String[] getInitServices() {
- String initServices =
properties.getProperty(PROP_PREFIX_INIT_SERVICES);
+ String initServices = properties.getProperty(PROP_INIT_SERVICES);
if (StringUtils.isBlank(initServices)) {
return new String[0];
@@ -46,6 +47,10 @@ public String[] getInitServices() {
return initServices.split(",");
}
+ public String getAppType() {
+ return properties.getProperty(PROP_APP_TYPE);
+ }
+
public Properties getAuditProperties() {
Properties ret = new Properties();
diff --git
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerEmbeddedAuthorizer.java
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerEmbeddedAuthorizer.java
index d76d04a46..8d77570df 100644
---
a/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerEmbeddedAuthorizer.java
+++
b/authz-embedded/src/main/java/org/apache/ranger/authz/embedded/RangerEmbeddedAuthorizer.java
@@ -48,17 +48,21 @@ public class RangerEmbeddedAuthorizer extends
RangerAuthorizer {
private static final Logger LOG =
LoggerFactory.getLogger(RangerEmbeddedAuthorizer.class);
private final RangerAuthzConfig config;
+ private final String appType;
private final Map<String, RangerAuthzPlugin> plugins = new HashMap<>();
public RangerEmbeddedAuthorizer(Properties properties) {
super(properties);
- this.config = new RangerAuthzConfig(properties);
+ this.config = new RangerAuthzConfig(properties);
+ this.appType = config.getAppType();
}
@Override
public void init() throws RangerAuthzException {
- AuditProviderFactory.getInstance().init(config.getAuditProperties(),
"ranger-authz");
+ String appType = StringUtils.isNotBlank(this.appType) ? this.appType :
"ranger-authz";
+
+ AuditProviderFactory.getInstance().init(config.getAuditProperties(),
appType);
String[] initServices = config.getInitServices();
@@ -83,8 +87,9 @@ public RangerAuthzResult authorize(RangerAuthzRequest
request) throws RangerAuth
validateRequest(request);
RangerAuthzPlugin plugin =
getOrCreatePlugin(request.getContext().getServiceName(),
request.getContext().getServiceType());
+ String appType = StringUtils.isNotBlank(this.appType) ?
this.appType : plugin.getPlugin().getAppId();
- try (RangerAuthzAuditHandler auditHandler = new
RangerAuthzAuditHandler(plugin.getPlugin())) {
+ try (RangerAuthzAuditHandler auditHandler = new
RangerAuthzAuditHandler(appType)) {
return authorize(request, plugin, auditHandler);
}
}
@@ -93,45 +98,28 @@ public RangerAuthzResult authorize(RangerAuthzRequest
request) throws RangerAuth
public RangerMultiAuthzResult authorize(RangerMultiAuthzRequest request)
throws RangerAuthzException {
validateRequest(request);
- RangerAuthzPlugin plugin =
getOrCreatePlugin(request.getContext().getServiceName(),
request.getContext().getServiceType());
- RangerMultiAuthzResult result = new
RangerMultiAuthzResult(request.getRequestId());
+ RangerAuthzPlugin plugin =
getOrCreatePlugin(request.getContext().getServiceName(),
request.getContext().getServiceType());
+ String appType = StringUtils.isNotBlank(this.appType) ?
this.appType : plugin.getPlugin().getAppId();
- if (request.getAccesses() != null) {
- int allowedCount = 0;
- int deniedCount = 0;
- int notDeterminedCount = 0;
+ try (RangerAuthzAuditHandler auditHandler = new
RangerAuthzAuditHandler(appType)) {
+ return authorize(request, plugin, auditHandler);
+ }
+ }
- result.setAccesses(new ArrayList<>(request.getAccesses().size()));
+ public RangerAuthzResult authorize(RangerAuthzRequest request,
RangerAuthzAuditHandler auditHandler) throws RangerAuthzException {
+ validateRequest(request);
- try (RangerAuthzAuditHandler auditHandler = new
RangerAuthzAuditHandler(plugin.getPlugin())) {
- for (RangerAccessInfo accessInfo : request.getAccesses()) {
- RangerAuthzRequest authzRequest = new
RangerAuthzRequest(null, request.getUser(), accessInfo, request.getContext());
- RangerAuthzResult authzResult = authorize(authzRequest,
plugin, auditHandler);
+ RangerAuthzPlugin plugin =
getOrCreatePlugin(request.getContext().getServiceName(),
request.getContext().getServiceType());
- if (authzResult.getDecision() == AccessDecision.ALLOW) {
- allowedCount++;
- } else if (authzResult.getDecision() ==
AccessDecision.DENY) {
- deniedCount++;
- } else if (authzResult.getDecision() ==
AccessDecision.NOT_DETERMINED) {
- notDeterminedCount++;
- }
+ return authorize(request, plugin, auditHandler);
+ }
- result.getAccesses().add(authzResult);
- }
- }
+ public RangerMultiAuthzResult authorize(RangerMultiAuthzRequest request,
RangerAuthzAuditHandler auditHandler) throws RangerAuthzException {
+ validateRequest(request);
- if (allowedCount == request.getAccesses().size()) {
- result.setDecision(AccessDecision.ALLOW);
- } else if (deniedCount == request.getAccesses().size()) {
- result.setDecision(AccessDecision.DENY);
- } else if (notDeterminedCount == request.getAccesses().size()) {
- result.setDecision(AccessDecision.NOT_DETERMINED);
- } else {
- result.setDecision(AccessDecision.PARTIAL);
- }
- }
+ RangerAuthzPlugin plugin =
getOrCreatePlugin(request.getContext().getServiceName(),
request.getContext().getServiceType());
- return result;
+ return authorize(request, plugin, auditHandler);
}
@Override
@@ -179,6 +167,45 @@ private RangerAuthzResult authorize(RangerAuthzRequest
request, RangerAuthzPlugi
return plugin.authorize(request, auditHandler);
}
+ private RangerMultiAuthzResult authorize(RangerMultiAuthzRequest request,
RangerAuthzPlugin plugin, RangerAuthzAuditHandler auditHandler) throws
RangerAuthzException {
+ RangerMultiAuthzResult result = new
RangerMultiAuthzResult(request.getRequestId());
+
+ if (request.getAccesses() != null) {
+ int allowedCount = 0;
+ int deniedCount = 0;
+ int notDeterminedCount = 0;
+
+ result.setAccesses(new ArrayList<>(request.getAccesses().size()));
+
+ for (RangerAccessInfo accessInfo : request.getAccesses()) {
+ RangerAuthzRequest authzRequest = new RangerAuthzRequest(null,
request.getUser(), accessInfo, request.getContext());
+ RangerAuthzResult authzResult = authorize(authzRequest,
plugin, auditHandler);
+
+ if (authzResult.getDecision() == AccessDecision.ALLOW) {
+ allowedCount++;
+ } else if (authzResult.getDecision() == AccessDecision.DENY) {
+ deniedCount++;
+ } else if (authzResult.getDecision() ==
AccessDecision.NOT_DETERMINED) {
+ notDeterminedCount++;
+ }
+
+ result.getAccesses().add(authzResult);
+ }
+
+ if (allowedCount == request.getAccesses().size()) {
+ result.setDecision(AccessDecision.ALLOW);
+ } else if (deniedCount == request.getAccesses().size()) {
+ result.setDecision(AccessDecision.DENY);
+ } else if (notDeterminedCount == request.getAccesses().size()) {
+ result.setDecision(AccessDecision.NOT_DETERMINED);
+ } else {
+ result.setDecision(AccessDecision.PARTIAL);
+ }
+ }
+
+ return result;
+ }
+
private RangerAuthzPlugin getOrCreatePlugin(String serviceName, String
serviceType) throws RangerAuthzException {
RangerAuthzPlugin ret = plugins.get(serviceName);
diff --git
a/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestEmbeddedAuthorizer.java
b/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestEmbeddedAuthorizer.java
index 5636ae3c2..91b1db792 100644
---
a/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestEmbeddedAuthorizer.java
+++
b/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestEmbeddedAuthorizer.java
@@ -22,6 +22,7 @@
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.authz.model.RangerAccessContext;
import org.apache.ranger.authz.model.RangerAuthzRequest;
import org.apache.ranger.authz.model.RangerAuthzResult;
@@ -32,6 +33,7 @@
import org.junit.jupiter.api.Test;
import java.io.InputStream;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
@@ -111,11 +113,21 @@ private void runAuthzTest(String testName) throws
Exception {
continue;
}
- RangerAuthzRequest request = test.request;
+ RangerAuthzRequest request = test.request;
RangerAuthzResult expected = test.result;
- RangerAuthzResult result = authorizer.authorize(request);
- assertEquals(expected, result);
+ if (test.audits == null) {
+ RangerAuthzResult result = authorizer.authorize(request);
+
+ assertEquals(expected, result);
+ } else {
+ try (TestAuthzAuditHandler auditHandler = new
TestAuthzAuditHandler("test")) {
+ RangerAuthzResult result =
authorizer.authorize(request, auditHandler);
+
+ assertEquals(expected, result);
+ auditEquals(test.audits,
auditHandler.getAuditEvents());
+ }
+ }
}
} finally {
if (authorizer != null) {
@@ -142,9 +154,19 @@ private void runMultiAuthzTest(String testName) throws
Exception {
RangerMultiAuthzRequest request = test.request;
RangerMultiAuthzResult expected = test.result;
- RangerMultiAuthzResult result =
authorizer.authorize(request);
- assertEquals(expected, result);
+ if (test.audits == null) {
+ RangerMultiAuthzResult result =
authorizer.authorize(request);
+
+ assertEquals(expected, result);
+ } else {
+ try (TestAuthzAuditHandler auditHandler = new
TestAuthzAuditHandler("test")) {
+ RangerMultiAuthzResult result =
authorizer.authorize(request, auditHandler);
+
+ assertEquals(expected, result);
+ auditEquals(test.audits,
auditHandler.getAuditEvents());
+ }
+ }
}
} finally {
if (authorizer != null) {
@@ -187,14 +209,39 @@ private List<TestResourcePermissionsData>
loadTestResourcePermissionsData(String
}
}
+ private static void auditEquals(List<AuthzAuditEvent> expected,
Collection<AuthzAuditEvent> actual) {
+ assertEquals(expected.size(), actual.size());
+
+ AuthzAuditEvent[] actualAudits = actual.toArray(new
AuthzAuditEvent[0]);
+
+ for (int i = 0; i < expected.size(); i++) {
+ auditEquals(expected.get(i), actualAudits[i]);
+ }
+ }
+
+ private static void auditEquals(AuthzAuditEvent expected, AuthzAuditEvent
actual) {
+ assertEquals(expected.getUser(), actual.getUser());
+ assertEquals(expected.getAccessType(), actual.getAccessType());
+ assertEquals(expected.getAction(), actual.getAction());
+ assertEquals(expected.getRepositoryName(), actual.getRepositoryName());
+ assertEquals(expected.getResourceType(), actual.getResourceType());
+ assertEquals(expected.getResourcePath(), actual.getResourcePath());
+ assertEquals(expected.getAccessResult(), actual.getAccessResult());
+ assertEquals(expected.getPolicyId(), actual.getPolicyId());
+ assertEquals(expected.getAgentId(), actual.getAgentId());
+ assertEquals(expected.getAclEnforcer(), actual.getAclEnforcer());
+ }
+
private static class TestAuthzData {
- public RangerAuthzRequest request;
- public RangerAuthzResult result;
+ public RangerAuthzRequest request;
+ public RangerAuthzResult result;
+ public List<AuthzAuditEvent> audits;
}
private static class TestMultiAuthzData {
public RangerMultiAuthzRequest request;
public RangerMultiAuthzResult result;
+ public List<AuthzAuditEvent> audits;
}
private static class TestResourcePermissionsData {
@@ -202,4 +249,14 @@ private static class TestResourcePermissionsData {
public RangerAccessContext context;
public RangerResourcePermissions permissions;
}
+
+ private static class TestAuthzAuditHandler extends RangerAuthzAuditHandler
{
+ public TestAuthzAuditHandler(String appType) {
+ super(appType);
+ }
+
+ public Collection<AuthzAuditEvent> getAuditEvents() {
+ return super.getAuditEvents();
+ }
+ }
}
diff --git
a/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestRangerAuthzConfig.java
b/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestRangerAuthzConfig.java
index fd9c77a1b..da84da4b6 100644
---
a/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestRangerAuthzConfig.java
+++
b/authz-embedded/src/test/java/org/apache/ranger/authz/embedded/TestRangerAuthzConfig.java
@@ -24,6 +24,7 @@
import java.util.Properties;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestRangerAuthzConfig {
@@ -35,6 +36,7 @@ public void testEmptyConfig() {
assertTrue(config.getServiceProperties("prod_hive", "hive").isEmpty());
assertTrue(config.getServiceProperties("dev_hdfs", "hdfs").isEmpty());
assertTrue(config.getAuditProperties().isEmpty());
+ assertNull(config.getAppType());
}
@Test
@@ -44,6 +46,7 @@ public void testDefaultConfigs() {
validateDevHiveProperties(config.getServiceProperties("dev_hive",
"hive"));
validateProdHiveProperties(config.getServiceProperties("prod_hive",
"hive"));
validateDevHdfsProperties(config.getServiceProperties("dev_hdfs",
"hdfs"));
+ assertEquals("ranger-pdp", config.getAppType());
}
@Test
@@ -75,6 +78,7 @@ public void testAllAuthzConfigs() {
validateDevHdfsProperties(config.getServiceProperties("dev_hdfs",
"hdfs"));
validateAuditConfigV2(config.getAuditProperties());
validateAuditConfigV3(config.getAuditProperties());
+ assertEquals("ranger-pdp", config.getAppType());
}
private void validateDevHiveProperties(Properties prop) {
@@ -156,6 +160,8 @@ private void validateAuditConfigV3(Properties props) {
private static Properties createDefaultProperties() {
Properties props = new Properties();
+ props.setProperty("ranger.authz.app.type", "ranger-pdp");
+
props.setProperty("ranger.authz.default.policy.source.impl",
"org.apache.ranger.admin.client.RangerAdminRESTClient");
props.setProperty("ranger.authz.default.policy.rest.url",
"http://localhost:6080");
props.setProperty("ranger.authz.default.policy.rest.ssl.config.file",
"/etc/hive/conf/ranger-policymgr-ssl.xml");
diff --git a/authz-embedded/src/test/resources/test_hive/tests_authz.json
b/authz-embedded/src/test/resources/test_hive/tests_authz.json
index 1d25ef073..6ed5d6b16 100644
--- a/authz-embedded/src/test/resources/test_hive/tests_authz.json
+++ b/authz-embedded/src/test/resources/test_hive/tests_authz.json
@@ -15,7 +15,12 @@
"permissions": {
"select": { "permission": "select", "access": { "decision": "ALLOW",
"policy": { "id": 1, "version": 1 } } }
}
- }
+ },
+ "audits": [
+ {
+ "reqUser": "tbl1-r-user", "access": "select", "action": "select",
"repo": "dev_hive", "resType": "table", "resource": "mydb/tbl1", "result": 1,
"policy": 1, "agent": "test", "enforcer": "ranger-acl"
+ }
+ ]
},
{
"request": {
diff --git a/authz-embedded/src/test/resources/test_s3/tests_multi_authz.json
b/authz-embedded/src/test/resources/test_s3/tests_multi_authz.json
index 407aa733a..f0f9f5bef 100644
--- a/authz-embedded/src/test/resources/test_s3/tests_multi_authz.json
+++ b/authz-embedded/src/test/resources/test_s3/tests_multi_authz.json
@@ -22,7 +22,12 @@
}
}
]
- }
+ },
+ "audits": [
+ {
+ "reqUser": "path1-r-user", "access": "read", "action": "read", "repo":
"dev_s3", "resType": "path", "resource": "mybucket/data/path1/file.orc",
"result": 1, "policy": 1, "agent": "test", "enforcer": "ranger-acl"
+ }
+ ]
},
{
"request": {