You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2016/09/02 00:01:27 UTC

[2/2] incubator-ranger git commit: RANGER-698: updated Ranger policies to support variables like {USER} in resource-names

RANGER-698: updated Ranger policies to support variables like {USER} in resource-names

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/c659d9aa
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/c659d9aa
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/c659d9aa

Branch: refs/heads/master
Commit: c659d9aa711595af9e701210484dc72cd8ff8985
Parents: a39c00f
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Thu Sep 1 07:39:58 2016 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 1 16:25:20 2016 -0700

----------------------------------------------------------------------
 ...rHiveResourcesAccessedTogetherCondition.java |   2 +-
 ...veResourcesNotAccessedTogetherCondition.java |   2 +-
 .../RangerServiceResourceMatcher.java           |   4 +-
 .../contextenricher/RangerTagEnricher.java      |  10 +-
 .../ranger/plugin/model/RangerServiceDef.java   |   2 +-
 .../plugin/policyengine/RangerPolicyEngine.java |   6 +-
 .../policyengine/RangerPolicyEngineImpl.java    |  21 +-
 .../RangerAbstractPolicyItemEvaluator.java      |   3 +-
 .../RangerCachedPolicyEvaluator.java            |  36 +--
 .../RangerDefaultPolicyEvaluator.java           |  82 +++---
 .../RangerDefaultPolicyItemEvaluator.java       |   8 +-
 .../RangerOptimizedPolicyEvaluator.java         |  22 +-
 .../policyevaluator/RangerPolicyEvaluator.java  |   6 +-
 .../RangerPolicyItemEvaluator.java              |   1 -
 .../RangerDefaultPolicyResourceMatcher.java     |  72 +++---
 .../RangerPolicyResourceMatcher.java            |  14 +-
 .../RangerAbstractResourceMatcher.java          | 248 ++++++++++++-------
 .../RangerDefaultResourceMatcher.java           |  20 +-
 .../RangerPathResourceMatcher.java              |  44 ++--
 .../resourcematcher/RangerResourceMatcher.java  |   8 +-
 .../plugin/resourcematcher/ResourceMatcher.java |  47 +++-
 .../plugin/util/RangerAccessRequestUtil.java    |  20 ++
 .../plugin/util/RangerRequestedResources.java   |   5 +-
 .../ranger/plugin/util/RangerResourceTrie.java  |  24 +-
 .../ranger/plugin/util/ServiceDefUtil.java      |  23 ++
 .../ranger/plugin/util/StringTokenReplacer.java | 126 ++++++++++
 .../RangerAbstractResourceMatcherTest.java      |   6 +-
 .../RangerDefaultResourceMatcherTest.java       |  30 ++-
 .../RangerPathResourceMatcherTest.java          |  40 +--
 .../resourcematcher/TestResourceMatcher.java    |  20 +-
 .../test_policyengine_hdfs_resourcespec.json    |  31 ++-
 .../test_resourcematcher_default.json           |  25 +-
 .../test_resourcematcher_dynamic.json           |  33 +++
 .../test_resourcematcher_path.json              |   2 +-
 ...resourcematcher_wildcards_as_delimiters.json |  28 +++
 .../org/apache/ranger/rest/PublicAPIsv2.java    |   4 +-
 .../org/apache/ranger/rest/ServiceREST.java     |  38 +--
 37 files changed, 809 insertions(+), 304 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
index fc9842e..b18e7cd 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
@@ -72,7 +72,7 @@ public class RangerHiveResourcesAccessedTogetherCondition extends RangerAbstract
 		if (isInitialized && CollectionUtils.isNotEmpty(matchers)) {
 			RangerRequestedResources resources = RangerAccessRequestUtil.getRequestedResourcesFromContext(request.getContext());
 
-			ret = resources == null ? false : !resources.isMutuallyExcluded(matchers);
+			ret = resources == null ? false : !resources.isMutuallyExcluded(matchers, request.getContext());
 		} else {
 			LOG.error("RangerHiveResourcesAccessedTogetherCondition.isMatched() - condition is not initialized correctly and will NOT be enforced");
 		}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
index 3b8e009..5036a06 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
@@ -72,7 +72,7 @@ public class RangerHiveResourcesNotAccessedTogetherCondition extends RangerAbstr
 		if (isInitialized && CollectionUtils.isNotEmpty(matchers)) {
 			RangerRequestedResources resources = RangerAccessRequestUtil.getRequestedResourcesFromContext(request.getContext());
 
-			ret = resources == null ? true : resources.isMutuallyExcluded(matchers);
+			ret = resources == null ? true : resources.isMutuallyExcluded(matchers, request.getContext());
 		} else {
 			LOG.error("RangerHiveResourcesNotAccessedTogetherCondition.isMatched() - Enforcer is not initialized correctly, Mutual Exclusion will NOT be enforced");
 		}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
index cf7b8e7..637423e 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
@@ -71,8 +71,8 @@ public class RangerServiceResourceMatcher implements RangerPolicyResourceEvaluat
 		return Long.compare(getId(), other.getId());
 	}
 
-	public boolean isMatch(RangerAccessResource requestedResource) {
-		return policyResourceMatcher != null ? policyResourceMatcher.isExactHeadMatch(requestedResource) : false;
+	public boolean isMatch(RangerAccessResource requestedResource, Map<String, Object> evalContext) {
+		return policyResourceMatcher != null ? policyResourceMatcher.isExactHeadMatch(requestedResource, evalContext) : false;
 	}
 
 	RangerServiceDef getServiceDef() {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 5b60a53..1a6e1b2 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -132,7 +132,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 			LOG.debug("==> RangerTagEnricher.enrich(" + request + ")");
 		}
 
-		List<RangerTag> matchedTags = findMatchingTags(request.getResource());
+		List<RangerTag> matchedTags = findMatchingTags(request.getResource(), request.getContext());
 
 		RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), matchedTags);
 
@@ -202,9 +202,9 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 		return ret;
 	}
 
-	private List<RangerTag> findMatchingTags(final RangerAccessResource resource) {
+	private List<RangerTag> findMatchingTags(final RangerAccessResource resource, final Map<String, Object> evalContext) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerTagEnricher.findMatchingTags(" + resource + ")");
+			LOG.debug("==> RangerTagEnricher.findMatchingTags(" + resource + ", " + evalContext + ")");
 		}
 
 		List<RangerTag> ret = null;
@@ -216,7 +216,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 
 			for (RangerServiceResourceMatcher resourceMatcher : serviceResourceMatchers) {
 
-				boolean matchResult = resourceMatcher.isMatch(resource);
+				boolean matchResult = resourceMatcher.isMatch(resource, evalContext);
 
 				if (matchResult) {
 					if (ret == null) {
@@ -237,7 +237,7 @@ public class RangerTagEnricher extends RangerAbstractContextEnricher {
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerTagEnricher.findMatchingTags(" + resource + ")");
+			LOG.debug("<== RangerTagEnricher.findMatchingTags(" + resource + ", " + evalContext + ")");
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index f6931b3..2d27961 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -1260,7 +1260,6 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 		private String              rbKeyDescription       = null;
 		private String              rbKeyValidationMessage = null;
 
-
 		public RangerResourceDef() {
 			this(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
 		}
@@ -1931,6 +1930,7 @@ public class RangerServiceDef extends RangerBaseModelObject implements java.io.S
 			result = prime * result + ((name == null) ? 0 : name.hashCode());
 			result = prime * result
 					+ ((rbKeyLabel == null) ? 0 : rbKeyLabel.hashCode());
+
 			return result;
 		}
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index a5e92da..698d99a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -37,6 +37,8 @@ public interface RangerPolicyEngine {
 	String AUDIT_NONE = "audit-none";
 	String AUDIT_DEFAULT = "audit-default";
 
+	String USER_CURRENT = "{USER}";
+
 	String getServiceName();
 
 	RangerServiceDef getServiceDef();
@@ -61,9 +63,9 @@ public interface RangerPolicyEngine {
 
 	boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType);
 
-	List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource);
+	List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources);
+	List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
 
 	List<RangerPolicy> getAllowedPolicies(String user, Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 6d3645f..9a63516 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -198,6 +198,8 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 			((RangerAccessRequestImpl) request).extractAndSetClientIPAddress(useForwardedIPAddress, trustedProxyAddresses);
 		}
 
+		RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
+
 		List<RangerContextEnricher> enrichers = allContextEnrichers;
 
 		if(!CollectionUtils.isEmpty(enrichers)) {
@@ -441,15 +443,15 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 	}
 
 	@Override
-	public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource) {
+	public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ")");
+			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext + ")");
 		}
 
 		List<RangerPolicy> ret = null;
 
 		for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
-			if (evaluator.isCompleteMatch(resource)) {
+			if (evaluator.isCompleteMatch(resource, evalContext)) {
 				if(ret == null) {
 					ret = new ArrayList<RangerPolicy>();
 				}
@@ -459,22 +461,22 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + "): " + ret);
+			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources) {
+	public List<RangerPolicy> getExactMatchPolicies(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ")");
+			LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ", " + evalContext + ")");
 		}
 
 		List<RangerPolicy> ret = null;
 
 		for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
-			if (evaluator.isCompleteMatch(resources)) {
+			if (evaluator.isCompleteMatch(resources, evalContext)) {
 				if(ret == null) {
 					ret = new ArrayList<RangerPolicy>();
 				}
@@ -484,7 +486,7 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + "): " + ret);
+			LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
@@ -652,8 +654,6 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
 
 					for (RangerPolicyEvaluator evaluator : evaluators) {
 						tagEvalResult.incrementEvaluatedPoliciesCount();
-						if(! evaluator.isMatch(tagEvalRequest.getResource())) 
-							continue;
 
 						evaluator.evaluate(tagEvalRequest, tagEvalResult);
 
@@ -953,6 +953,7 @@ class RangerTagAccessRequest extends RangerAccessRequestImpl {
 
 		RangerAccessRequestUtil.setCurrentTagInContext(request.getContext(), resourceTag);
 		RangerAccessRequestUtil.setCurrentResourceInContext(request.getContext(), request.getResource());
+		RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
 
 		super.setContext(requestContext);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index 514884f..b36bc1f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -120,7 +120,8 @@ public abstract class RangerAbstractPolicyItemEvaluator implements RangerPolicyI
 		int evalOrder = RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT;
 
 		if(policyItem != null) {
-			if(CollectionUtils.isNotEmpty(policyItem.getGroups()) && policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC)) {
+			if((CollectionUtils.isNotEmpty(policyItem.getGroups()) && policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC))
+				|| (CollectionUtils.isNotEmpty(policyItem.getUsers()) && policyItem.getUsers().contains(RangerPolicyEngine.USER_CURRENT))) {
 				evalOrder -= RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS;
 			} else {
 				int userGroupCount = 0;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
index 91a53d8..7711765 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
@@ -26,6 +26,8 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
+import java.util.Map;
+
 public class RangerCachedPolicyEvaluator extends RangerOptimizedPolicyEvaluator {
     private static final Log LOG = LogFactory.getLog(RangerCachedPolicyEvaluator.class);
 
@@ -47,34 +49,38 @@ public class RangerCachedPolicyEvaluator extends RangerOptimizedPolicyEvaluator
     }
 
     @Override
-    public boolean isMatch(RangerAccessResource resource) {
+    public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerCachedPolicyEvaluator.isMatch(" + resource + ")");
+            LOG.debug("==> RangerCachedPolicyEvaluator.isMatch(" + resource + ", " + evalContext + ")");
         }
 
         boolean result = false;
 
-        // Check in the evaluator-owned cache for the match, if found return. else call super.isMatch(), add result to cache
-        RangerResourceAccessCache.LookupResult lookup = cache.lookup(resource);
+        if (needsDynamicEval()) {
+            result = super.isMatch(resource, evalContext);
+        } else {
+            // Check in the evaluator-owned cache for the match, if found return. else call super.isMatch(), add result to cache
+            RangerResourceAccessCache.LookupResult lookup = cache.lookup(resource);
 
-        if (lookup != RangerResourceAccessCache.LookupResult.IN_NOTMATCHED_CACHE) {
-            // We dont know definitely that this previously not matched
-            if (lookup != RangerResourceAccessCache.LookupResult.IN_MATCHED_CACHE) {
-                result = super.isMatch(resource);
+            if (lookup != RangerResourceAccessCache.LookupResult.IN_NOTMATCHED_CACHE) {
+                // We dont know definitely that this previously not matched
+                if (lookup != RangerResourceAccessCache.LookupResult.IN_MATCHED_CACHE) {
+                    result = super.isMatch(resource, evalContext);
 
-                // update the cache with the result of the match
-                if(result) {
-	                cache.add(resource, RangerResourceAccessCache.CacheType.MATCHED_CACHE);
+                    // update the cache with the result of the match
+                    if (result) {
+                        cache.add(resource, RangerResourceAccessCache.CacheType.MATCHED_CACHE);
+                    } else {
+                        cache.add(resource, RangerResourceAccessCache.CacheType.NOTMATCHED_CACHE);
+                    }
                 } else {
-	                cache.add(resource, RangerResourceAccessCache.CacheType.NOTMATCHED_CACHE);
+                    result = true;
                 }
-            } else {
-                result = true;
             }
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerCachedPolicyEvaluator.isMatch(" + resource + "): " + result);
+            LOG.debug("<== RangerCachedPolicyEvaluator.isMatch(" + resource + ", " + evalContext + "): " + result);
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index eb46353..867cd20 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -52,6 +52,7 @@ import org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.ServiceDefUtil;
 
@@ -70,8 +71,11 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	private int                             customConditionsCount    = 0;
 	private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators  = null;
 	private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators = null;
+
 	private String perfTag;
 
+	protected boolean needsDynamicEval() { return resourceMatcher != null ? resourceMatcher.getNeedsDynamicEval() : false; }
+
 	@Override
 	public int getCustomConditionsCount() {
 		return customConditionsCount;
@@ -170,14 +174,14 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
             if (!result.getIsAuditedDetermined()) {
                 // Need to match request.resource first. If it matches (or head matches), then only more progress can be made
                 if (!isResourceMatchAttempted) {
-                    isResourceMatch = isMatch(request.getResource());
+                    isResourceMatch = isMatch(request.getResource(), request.getContext());
                     isResourceMatchAttempted = true;
                 }
 
                 // Try head match only if match was not found and ANY access was requested
                 if (!isResourceMatch) {
                     if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-                        isResourceHeadMatch = matchResourceHead(request.getResource());
+                        isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
                         isResourceHeadMatchAttempted = true;
                     }
                 }
@@ -196,7 +200,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
                 if (hasMatchablePolicyItem(request)) {
                     // Try Match only if it was not attempted as part of evaluating Audit requirement
                     if (!isResourceMatchAttempted) {
-                        isResourceMatch = isMatch(request.getResource());
+                        isResourceMatch = isMatch(request.getResource(), request.getContext());
                         isResourceMatchAttempted = true;
                     }
 
@@ -204,7 +208,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
                     // Audit requirement
                     if (!isResourceMatch) {
                         if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-                            isResourceHeadMatch = matchResourceHead(request.getResource());
+                            isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
                             isResourceHeadMatchAttempted = true;
                         }
                     }
@@ -245,13 +249,13 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 			if (!result.getIsAuditedDetermined()) {
 				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
+					isResourceMatch = isMatch(request.getResource(), request.getContext());
 					isResourceMatchAttempted = true;
 				}
 
 				if (!isResourceMatch) {
 					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
 						isResourceHeadMatchAttempted = true;
 					}
 				}
@@ -266,13 +270,13 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 			if (!result.getIsAccessDetermined()) {
 				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
+					isResourceMatch = isMatch(request.getResource(), request.getContext());
 					isResourceMatchAttempted = true;
 				}
 
 				if (!isResourceMatch) {
 					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
 						isResourceHeadMatchAttempted = true;
 					}
 				}
@@ -312,13 +316,13 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 			if (!result.getIsAuditedDetermined()) {
 				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
+					isResourceMatch = isMatch(request.getResource(), request.getContext());
 					isResourceMatchAttempted = true;
 				}
 
 				if (!isResourceMatch) {
 					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
 						isResourceHeadMatchAttempted = true;
 					}
 				}
@@ -333,13 +337,13 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 
 			if (!result.getIsAccessDetermined()) {
 				if (!isResourceMatchAttempted) {
-					isResourceMatch = isMatch(request.getResource());
+					isResourceMatch = isMatch(request.getResource(), request.getContext());
 					isResourceMatchAttempted = true;
 				}
 
 				if (!isResourceMatch) {
 					if (attemptResourceHeadMatch && !isResourceHeadMatchAttempted) {
-						isResourceHeadMatch = matchResourceHead(request.getResource());
+						isResourceHeadMatch = matchResourceHead(request.getResource(), request.getContext());
 						isResourceHeadMatchAttempted = true;
 					}
 				}
@@ -358,9 +362,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 	@Override
-	public boolean isMatch(RangerAccessResource resource) {
+	public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -368,32 +372,32 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 		RangerPerfTracer perf = null;
 
 		if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
-			perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + perfTag + ")");
+			perf = RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, "RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + evalContext + "," + perfTag + ")");
 		}
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isMatch(resource);
+			ret = resourceMatcher.isMatch(resource, evalContext);
 		}
 
 		RangerPerfTracer.log(perf);
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + resource + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public boolean isCompleteMatch(RangerAccessResource resource) {
+	public boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isCompleteMatch(resource);
+			ret = resourceMatcher.isCompleteMatch(resource, evalContext);
 		}
 
 		if(LOG.isDebugEnabled()) {
@@ -404,19 +408,19 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 	@Override
-	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources) {
+	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isCompleteMatch(resources);
+			ret = resourceMatcher.isCompleteMatch(resources, evalContext);
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
@@ -428,7 +432,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + ")");
 		}
 
-		boolean ret = isAccessAllowed(user, userGroups, accessType) && isMatch(resource);
+		Map<String, Object> evalContext = new HashMap<String, Object>();
+		RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
+
+		boolean ret = isAccessAllowed(user, userGroups, accessType) && isMatch(resource, evalContext);
 		
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
@@ -443,7 +450,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + ")");
 		}
 
-		boolean ret = isAccessAllowed(user, userGroups, accessType) && isMatch(resources);
+		Map<String, Object> evalContext = new HashMap<String, Object>();
+		RangerAccessRequestUtil.setCurrentUserInContext(evalContext, user);
+
+		boolean ret = isAccessAllowed(user, userGroups, accessType) && isMatch(resources, evalContext);
 		
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
@@ -458,9 +468,9 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 			LOG.debug("==> RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + result + ")");
 		}
 
-		final boolean isResourceMatch          = isMatch(request.getResource());
+		final boolean isResourceMatch          = isMatch(request.getResource(), request.getContext());
 		final boolean attemptResourceHeadMatch = request.isAccessTypeAny() || request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-		final boolean isResourceHeadMatch      = (!isResourceMatch && attemptResourceHeadMatch) ? matchResourceHead(request.getResource()) : false;
+		final boolean isResourceHeadMatch      = (!isResourceMatch && attemptResourceHeadMatch) ? matchResourceHead(request.getResource(), request.getContext()) : false;
 
 		if(isResourceMatch || isResourceHeadMatch) {
 			if (CollectionUtils.isNotEmpty(allowEvaluators)) {
@@ -643,37 +653,37 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
 	}
 
 
-	protected boolean matchResourceHead(RangerAccessResource resource) {
+	protected boolean matchResourceHead(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isHeadMatch(resource);
+			ret = resourceMatcher.isHeadMatch(resource, evalContext);
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
-	protected boolean isMatch(Map<String, RangerPolicyResource> resources) {
+	protected boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resources + ")");
+			LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resources + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
 
 		if(resourceMatcher != null) {
-			ret = resourceMatcher.isMatch(resources);
+			ret = resourceMatcher.isMatch(resources, evalContext);
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + resources + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + resources + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index e2c715f..b899dd1 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -20,6 +20,7 @@ package org.apache.ranger.plugin.policyevaluator;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
@@ -48,6 +49,8 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 	private static final Log PERF_POLICYCONDITION_INIT_LOG = RangerPerfTracer.getPerfLogger("policycondition.init");
 	private static final Log PERF_POLICYCONDITION_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policycondition.request");
 
+	private boolean hasCurrentUser = false;
+
 	public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int policyItemIndex, RangerPolicyEngineOptions options) {
 		super(serviceDef, policy, policyItem, policyItemType, policyItemIndex, options);
 	}
@@ -100,6 +103,9 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 			RangerPerfTracer.log(perf);
 		}
 
+		List<String> users = policyItem != null ? policyItem.getUsers() : null;
+		this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.USER_CURRENT);
+
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", conditionsCount=" + getConditionEvaluators().size() + ")");
 		}
@@ -172,7 +178,7 @@ public class RangerDefaultPolicyItemEvaluator extends RangerAbstractPolicyItemEv
 
 		if(policyItem != null) {
 			if(!ret && user != null && policyItem.getUsers() != null) {
-				ret = policyItem.getUsers().contains(user);
+				ret = hasCurrentUser || policyItem.getUsers().contains(user);
 			}
 
 			if(!ret && userGroups != null && policyItem.getGroups() != null) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index 00b24d1..fb854d0 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -40,7 +40,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
     private boolean     delegateAdmin  = false;
     private boolean     hasAllPerms    = false;
     private boolean     hasPublicGroup = false;
-
+    private boolean     hasCurrentUser = false;
 
     // For computation of priority
     private static final String RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING   = "*";
@@ -59,7 +59,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
     private static final int RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_IS_EXCLUDES                      =  5;
     private static final int RANGER_POLICY_EVAL_SCORE_RESORUCE_DISCOUNT_IS_RECURSIVE                     =  5;
     private static final int RANGER_POLICY_EVAL_SCORE_CUSTOM_CONDITION_PENALTY                           =  5;
-
+    private static final int RANGER_POLICY_EVAL_SCORE_DYNAMIC_RESOURCE_EVAL_PENALTY                      =  20;
 
     @Override
     public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
@@ -77,9 +77,17 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
 
         hasAllPerms = checkIfHasAllPerms();
 
+        for (String user : users) {
+            if (user.equalsIgnoreCase(RangerPolicyEngine.USER_CURRENT)) {
+                hasCurrentUser = true;
+                break;
+            }
+        }
+
         for (String group : groups) {
             if (group.equalsIgnoreCase(RangerPolicyEngine.GROUP_PUBLIC)) {
                 hasPublicGroup = true;
+                break;
             }
         }
 
@@ -185,10 +193,13 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
                 }
             }
         }
+        if (needsDynamicEval()) {
+            evalOrder += RANGER_POLICY_EVAL_SCORE_DYNAMIC_RESOURCE_EVAL_PENALTY;
+        }
 
         evalOrder -= Math.min(RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_RESOURCE, resourceDiscount);
 
-        if (hasPublicGroup) {
+        if (hasPublicGroup || hasCurrentUser) {
             evalOrder -= RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS;
         } else {
             evalOrder -= Math.min(groups.size() + users.size(), RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS);
@@ -227,7 +238,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
     protected boolean hasMatchablePolicyItem(RangerAccessRequest request) {
         boolean ret = false;
 
-        if (hasPublicGroup || users.contains(request.getUser()) || CollectionUtils.containsAny(groups, request.getUserGroups())) {
+        if (hasPublicGroup || hasCurrentUser || users.contains(request.getUser()) || CollectionUtils.containsAny(groups, request.getUserGroups())) {
             if(request.isAccessTypeDelegatedAdmin()) {
                 ret = delegateAdmin;
             } else if(hasAllPerms) {
@@ -243,7 +254,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
     private boolean hasMatchablePolicyItem(String user, Set<String> userGroups, String accessType) {
         boolean ret = false;
 
-        if (hasPublicGroup || users.contains(user) || CollectionUtils.containsAny(groups, userGroups)) {
+        if (hasPublicGroup || hasCurrentUser || users.contains(user) || CollectionUtils.containsAny(groups, userGroups)) {
             boolean isAdminAccess = StringUtils.equals(accessType, RangerPolicyEngine.ADMIN_ACCESS);
 
             if(isAdminAccess) {
@@ -276,6 +287,7 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
 
 	            groups.addAll(item.getGroups());
 	            users.addAll(item.getUsers());
+
 	        }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index b60e06e..92f1592 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -71,11 +71,11 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
 
 	void evaluate(RangerAccessRequest request, RangerRowFilterResult result);
 
-	boolean isMatch(RangerAccessResource resource);
+	boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(RangerAccessResource resource);
+	boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
+	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
 
 	boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index 80e46f5..20b08c8 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -47,7 +47,6 @@ public interface RangerPolicyItemEvaluator extends Comparable<RangerPolicyItemEv
 
 	int getEvalOrder();
 
-
 	boolean isMatch(RangerAccessRequest request);
 
 	boolean matchUserGroup(String user, Set<String> userGroups);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index 8bde807..5444e2b 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -48,6 +48,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	protected Map<String, RangerPolicyResource> policyResources = null;
 
 	private Map<String, RangerResourceMatcher> matchers = null;
+	private boolean                            needsDynamicEval = false;
 	private List<RangerResourceDef> firstValidResourceDefHierarchy;
 
 	@Override
@@ -68,6 +69,11 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
+	public boolean getNeedsDynamicEval() {
+		return needsDynamicEval;
+	}
+
+	@Override
 	public void init() {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> RangerDefaultPolicyResourceMatcher.init()");
@@ -133,6 +139,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 							RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource);
 
 							if (matcher != null) {
+								if (!needsDynamicEval && matcher.getNeedsDynamicEval()) {
+									needsDynamicEval = true;
+								}
 								matchers.put(resourceName, matcher);
 							} else {
 								LOG.error("failed to find matcher for resource " + resourceName);
@@ -189,10 +198,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		return matchers != null ? matchers.get(resourceName) : null;
 	}
 
-	@Override
-	public boolean isMatch(RangerAccessResource resource) {
+	public boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -211,9 +219,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 					// when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource
 					if(StringUtils.isEmpty(resourceValue)) {
-						ret = matcher == null || matcher.isMatch(resourceValue);
+						ret = matcher == null || matcher.isMatch(resourceValue, evalContext);
 					} else {
-						ret = matcher != null && matcher.isMatch(resourceValue);
+						ret = matcher != null && matcher.isMatch(resourceValue, evalContext);
 					}
 
 					if(! ret) {
@@ -228,7 +236,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resource  + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
@@ -236,9 +244,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 
 	@Override
-	public boolean isMatch(Map<String, RangerPolicyResource> resources) {
+	public boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resources + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isMatch(" + resources  + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -257,10 +265,10 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 					// when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource
 					if(resourceValues == null || CollectionUtils.isEmpty(resourceValues.getValues())) {
-						ret = matcher == null || matcher.isMatch(null);
+						ret = matcher == null || matcher.isMatch(null, null);
 					} else if(matcher != null) {
 						for(String resourceValue : resourceValues.getValues()) {
-							ret = matcher.isMatch(resourceValue);
+							ret = matcher.isMatch(resourceValue, evalContext);
 
 							if(! ret) {
 								break;
@@ -280,16 +288,16 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resources + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isMatch(" + resources  + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public boolean isCompleteMatch(RangerAccessResource resource) {
+	public boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource  + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -311,9 +319,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 					RangerResourceMatcher matcher       = matchers == null ? null : matchers.get(resourceName);
 
 					if(StringUtils.isEmpty(resourceValue)) {
-						ret = matcher == null || matcher.isCompleteMatch(resourceValue);
+						ret = matcher == null || matcher.isCompleteMatch(resourceValue, evalContext);
 					} else {
-						ret = matcher != null && matcher.isCompleteMatch(resourceValue);
+						ret = matcher != null && matcher.isCompleteMatch(resourceValue, evalContext);
 					}
 
 					if(! ret) {
@@ -328,21 +336,21 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource  + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public boolean isHeadMatch(RangerAccessResource resource) {
+	public boolean isHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
-		
+
 		if (matchers == null) {
 
 			LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch(): PolicyResourceMatcher not initialized correctly!!!");
@@ -355,22 +363,22 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 		} else {
 
-			ret = newIsHeadMatch(resource);
+			ret = newIsHeadMatch(resource, evalContext);
 
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ", " + evalContext  + "): " + ret);
 		}
 
 		return ret;
 	}
 
 	@Override
-	public boolean isExactHeadMatch(RangerAccessResource resource) {
+	public boolean isExactHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -392,21 +400,21 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 		} else {
 
-			ret = newIsHeadMatch(resource);
+			ret = newIsHeadMatch(resource, evalContext);
 
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")" + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + evalContext + ")" + ret);
 		}
 
 		return ret;
 	}
 
-	private boolean newIsHeadMatch(RangerAccessResource resource) {
+	private boolean newIsHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext) {
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean skipped = false;
@@ -424,7 +432,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 
 					if (!skipped) {
 
-						matched = matcher.isMatch(resourceValue);
+						matched = matcher.isMatch(resourceValue, evalContext);
 
 					} else {
 
@@ -444,7 +452,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		}
 
 		if (LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + "): " + matched);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + evalContext + "): " + matched);
 		}
 
 		return matched;
@@ -520,9 +528,9 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
-	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources) {
+	public boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ")");
+			LOG.debug("==> RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -561,7 +569,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + "): " + ret);
+			LOG.debug("<== RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index a8810e5..ea0f36c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -40,17 +40,19 @@ public interface RangerPolicyResourceMatcher {
 
 	RangerResourceMatcher getResourceMatcher(String resourceName);
 
-	boolean isMatch(RangerAccessResource resource);
+	boolean isMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isMatch(Map<String, RangerPolicyResource> resources);
+	boolean isMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(RangerAccessResource resource);
+	boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isHeadMatch(RangerAccessResource resource);
+	boolean isHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isExactHeadMatch(RangerAccessResource resource);
+	boolean isExactHeadMatch(RangerAccessResource resource, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
+	boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
+
+	boolean getNeedsDynamicEval();
 
 	StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
index 574f2eb..864709c 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -32,18 +32,21 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 
 
 public abstract class RangerAbstractResourceMatcher implements RangerResourceMatcher {
 	private static final Log LOG = LogFactory.getLog(RangerAbstractResourceMatcher.class);
 
 	public final static String WILDCARD_ASTERISK = "*";
-	public final static String WILDCARDS = "*?";
 
-	public final static String OPTIONS_SEP        = ";";
-	public final static String OPTION_NV_SEP      = "=";
 	public final static String OPTION_IGNORE_CASE = "ignoreCase";
 	public final static String OPTION_WILD_CARD   = "wildCard";
+	public final static String OPTION_REPLACE_TOKENS         = "replaceTokens";
+	public final static String OPTION_TOKEN_DELIMITER_START  = "tokenDelimiterStart";
+	public final static String OPTION_TOKEN_DELIMITER_END    = "tokenDelimiterEnd";
+	public final static String OPTION_TOKEN_DELIMITER_ESCAPE = "tokenDelimiterEscape";
+	public final static String OPTION_TOKEN_DELIMITER_PREFIX = "tokenDelimiterPrefix";
 
 	protected RangerResourceDef    resourceDef    = null;
 	protected RangerPolicyResource policyResource = null;
@@ -51,10 +54,16 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 	protected boolean      optIgnoreCase = false;
 	protected boolean      optWildCard   = false;
 
-	protected List<String> policyValues     = null;
-	protected boolean      policyIsExcludes = false;
-	protected boolean      isMatchAny       = false;
-	protected List<ResourceMatcher> resourceMatchers = null;
+	protected List<String> policyValues = null;
+	protected boolean policyIsExcludes = false;
+	protected boolean isMatchAny = false;
+	protected ResourceMatcherWrapper resourceMatchers = null;
+
+	protected boolean optReplaceTokens   = false;
+	protected char    startDelimiterChar = '{';
+	protected char    endDelimiterChar   = '}';
+	protected char    escapeChar         = '\\';
+	protected String  tokenPrefix        = "";
 
 	@Override
 	public void setResourceDef(RangerResourceDef resourceDef) {
@@ -72,13 +81,15 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 			LOG.debug("==> RangerAbstractResourceMatcher.init()");
 		}
 
-		optIgnoreCase = getBooleanOption(OPTION_IGNORE_CASE, true);
-		optWildCard   = getBooleanOption(OPTION_WILD_CARD, true);
+		Map<String, String> options = resourceDef != null ? resourceDef.getMatcherOptions() : null;
+
+		optIgnoreCase = getOptionIgnoreCase(options);
+		optWildCard   = getOptionWildCard(options);
 
-		policyValues     = new ArrayList<String>();
+		policyValues = new ArrayList<String>();
 		policyIsExcludes = policyResource == null ? false : policyResource.getIsExcludes();
 
-		if(policyResource != null && policyResource.getValues() != null) {
+		if (policyResource != null && policyResource.getValues() != null) {
 			for (String policyValue : policyResource.getValues()) {
 				if (StringUtils.isEmpty(policyValue)) {
 					continue;
@@ -86,8 +97,35 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 				policyValues.add(policyValue);
 			}
 		}
+
+		optReplaceTokens = getOptionReplaceTokens(options);
+
+		if(optReplaceTokens) {
+			startDelimiterChar = getOptionDelimiterStart(options);
+			endDelimiterChar   = getOptionDelimiterEnd(options);
+			escapeChar         = getOptionDelimiterEscape(options);
+			tokenPrefix        = getOptionDelimiterPrefix(options);
+
+			if(escapeChar == startDelimiterChar || escapeChar == endDelimiterChar ||
+					tokenPrefix.indexOf(escapeChar) != -1 || tokenPrefix.indexOf(startDelimiterChar) != -1 ||
+					tokenPrefix.indexOf(endDelimiterChar) != -1) {
+				String resouceName = resourceDef == null ? "" : resourceDef.getName();
+
+				String msg = "Invalid token-replacement parameters for resource '" + resouceName + "': { ";
+				msg += (OPTION_TOKEN_DELIMITER_START + "='" + startDelimiterChar + "'; ");
+				msg += (OPTION_TOKEN_DELIMITER_END + "='" + endDelimiterChar + "'; ");
+				msg += (OPTION_TOKEN_DELIMITER_ESCAPE + "='" + escapeChar + "'; ");
+				msg += (OPTION_TOKEN_DELIMITER_PREFIX + "='" + tokenPrefix + "' }. ");
+				msg += "Token replacement disabled";
+
+				LOG.error(msg);
+
+				optReplaceTokens = false;
+			}
+		}
+
 		resourceMatchers = buildResourceMatchers();
-		isMatchAny = CollectionUtils.isEmpty(resourceMatchers);
+		isMatchAny = resourceMatchers == null || CollectionUtils.isEmpty(resourceMatchers.getResourceMatchers());
 
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("<== RangerAbstractResourceMatcher.init()");
@@ -97,31 +135,66 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 	@Override
 	public boolean isMatchAny() { return isMatchAny; }
 
-	protected List<ResourceMatcher> buildResourceMatchers() {
-		List<ResourceMatcher> ret = new ArrayList<ResourceMatcher> ();
+	public boolean getNeedsDynamicEval() {
+		return resourceMatchers != null && resourceMatchers.getNeedsDynamicEval();
+	}
+
+	public static boolean getOptionIgnoreCase(Map<String, String> options) {
+		return ServiceDefUtil.getBooleanOption(options, OPTION_IGNORE_CASE, true);
+	}
+
+	public static boolean getOptionWildCard(Map<String, String> options) {
+		return ServiceDefUtil.getBooleanOption(options, OPTION_WILD_CARD, true);
+	}
+
+	public static boolean getOptionReplaceTokens(Map<String, String> options) {
+		return ServiceDefUtil.getBooleanOption(options, OPTION_REPLACE_TOKENS, true);
+	}
+
+	public static char getOptionDelimiterStart(Map<String, String> options) {
+		return ServiceDefUtil.getCharOption(options, OPTION_TOKEN_DELIMITER_START, '{');
+	}
+
+	public static char getOptionDelimiterEnd(Map<String, String> options) {
+		return ServiceDefUtil.getCharOption(options, OPTION_TOKEN_DELIMITER_END, '}');
+	}
+
+	public static char getOptionDelimiterEscape(Map<String, String> options) {
+		return ServiceDefUtil.getCharOption(options, OPTION_TOKEN_DELIMITER_ESCAPE, '\\');
+	}
+
+	public static String getOptionDelimiterPrefix(Map<String, String> options) {
+		return ServiceDefUtil.getOption(options, OPTION_TOKEN_DELIMITER_PREFIX, "");
+	}
+	protected ResourceMatcherWrapper buildResourceMatchers() {
+		List<ResourceMatcher> resourceMatchers = new ArrayList<ResourceMatcher>();
+		boolean needsDynamicEval = false;
 
 		for (String policyValue : policyValues) {
 			ResourceMatcher matcher = getMatcher(policyValue);
 
 			if (matcher != null) {
 				if (matcher.isMatchAny()) {
-					ret.clear();
+					resourceMatchers.clear();
 					break;
-				} else {
-					ret.add(matcher);
 				}
+				if (!needsDynamicEval && matcher.getNeedsDynamicEval()) {
+					needsDynamicEval = true;
+				}
+				resourceMatchers.add(matcher);
 			}
 		}
 
-		Collections.sort(ret);
+		Collections.sort(resourceMatchers);
 
-		return ret;
+		return CollectionUtils.isNotEmpty(resourceMatchers) ?
+				new ResourceMatcherWrapper(needsDynamicEval, resourceMatchers) : null;
 	}
 
 	@Override
-	public boolean isCompleteMatch(String resource) {
+	public boolean isCompleteMatch(String resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ")");
+			LOG.debug("==> RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -130,7 +203,7 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 			ret = StringUtils.isEmpty(resource);
 		} else if(policyValues.size() == 1) {
 			String policyValue = policyValues.get(0);
-			
+
 			if(isMatchAny) {
 				ret = StringUtils.containsOnly(resource, WILDCARD_ASTERISK);
 			} else {
@@ -143,53 +216,7 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerAbstractResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
-		}
-
-		return ret;
-	}
-
-
-	public String getOption(String name) {
-		String ret = null;
-
-		Map<String, String> options = resourceDef != null ? resourceDef.getMatcherOptions() : null;
-
-		if(options != null && name != null) {
-			ret = options.get(name);
-		}
-
-		return ret;
-	}
-
-	public String getOption(String name, String defaultValue) {
-		String ret = defaultValue;
-		String val = getOption(name);
-
-		if(val != null) {
-			ret = val;
-		}
-
-		return ret;
-	}
-
-	public boolean getBooleanOption(String name, boolean defaultValue) {
-		boolean ret = defaultValue;
-		String  val = getOption(name);
-
-		if(val != null) {
-			ret = Boolean.parseBoolean(val);
-		}
-
-		return ret;
-	}
-
-	public char getCharOption(String name, char defaultValue) {
-		char   ret = defaultValue;
-		String val = getOption(name);
-
-		if(! StringUtils.isEmpty(val)) {
-			ret = val.charAt(0);
+			LOG.debug("<== RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;
@@ -234,7 +261,7 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 		sb.append("options={");
 		if(resourceDef != null && resourceDef.getMatcherOptions() != null) {
 			for(Map.Entry<String, String> e : resourceDef.getMatcherOptions().entrySet()) {
-				sb.append(e.getKey()).append("=").append(e.getValue()).append(OPTIONS_SEP);
+				sb.append(e.getKey()).append("=").append(e.getValue()).append(';');
 			}
 		}
 		sb.append("} ");
@@ -320,6 +347,10 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat
 			ret = optIgnoreCase ? new CaseInsensitiveStartsWithMatcher(matchStr) : new CaseSensitiveStartsWithMatcher(matchStr);
 		}
 
+		if(optReplaceTokens) {
+			ret.setDelimiters(startDelimiterChar, endDelimiterChar, escapeChar, tokenPrefix);
+		}
+
 		return ret;
 	}
 }
@@ -329,19 +360,21 @@ final class CaseSensitiveStringMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return StringUtils.equals(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.equals(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() { return 1;}
+	int getPriority() { return 1 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveStringMatcher extends ResourceMatcher {
 	CaseInsensitiveStringMatcher(String value) { super(value); }
 
-	boolean isMatch(String str) {
-		return StringUtils.equalsIgnoreCase(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.equalsIgnoreCase(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() {return 2; }
+	int getPriority() {return 2 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveStartsWithMatcher extends ResourceMatcher {
@@ -349,19 +382,21 @@ final class CaseSensitiveStartsWithMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return StringUtils.startsWith(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.startsWith(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() { return 3;}
+	int getPriority() { return 3 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveStartsWithMatcher extends ResourceMatcher {
 	CaseInsensitiveStartsWithMatcher(String value) { super(value); }
 
-	boolean isMatch(String str) {
-		return StringUtils.startsWithIgnoreCase(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.startsWithIgnoreCase(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() { return 4; }
+	int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveEndsWithMatcher extends ResourceMatcher {
@@ -369,10 +404,11 @@ final class CaseSensitiveEndsWithMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return StringUtils.endsWith(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.endsWith(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() { return 3; }
+	int getPriority() { return 3 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseInsensitiveEndsWithMatcher extends ResourceMatcher {
@@ -380,10 +416,11 @@ final class CaseInsensitiveEndsWithMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return StringUtils.endsWithIgnoreCase(str, value);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return StringUtils.endsWithIgnoreCase(resourceValue, getExpandedValue(evalContext));
 	}
-	int getPriority() { return 4; }
+	int getPriority() { return 4 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveWildcardMatcher extends ResourceMatcher {
@@ -391,10 +428,11 @@ final class CaseSensitiveWildcardMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return FilenameUtils.wildcardMatch(str, value, IOCase.SENSITIVE);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return FilenameUtils.wildcardMatch(resourceValue, getExpandedValue(evalContext), IOCase.SENSITIVE);
 	}
-	int getPriority() { return 5; }
+	int getPriority() { return 5 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 
@@ -403,10 +441,32 @@ final class CaseInsensitiveWildcardMatcher extends ResourceMatcher {
 		super(value);
 	}
 
-	boolean isMatch(String str) {
-		return FilenameUtils.wildcardMatch(str, value, IOCase.INSENSITIVE);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return FilenameUtils.wildcardMatch(resourceValue, getExpandedValue(evalContext), IOCase.INSENSITIVE);
 	}
-	int getPriority() {return 6; }
+	int getPriority() {return 6 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0); }
+}
+
+final class ResourceMatcherWrapper {
+	private final boolean needsDynamicEval;
+	private final List<ResourceMatcher> resourceMatchers;
 
+	ResourceMatcherWrapper() {
+		this(false, null);
+	}
+
+	ResourceMatcherWrapper(boolean needsDynamicEval, List<ResourceMatcher> resourceMatchers) {
+		this.needsDynamicEval = needsDynamicEval;
+		this.resourceMatchers = resourceMatchers;
+	}
+
+	boolean getNeedsDynamicEval() {
+		return needsDynamicEval;
+	}
+
+	List<ResourceMatcher> getResourceMatchers() {
+		return resourceMatchers;
+	}
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
index 0a11be0..c1508bf 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
@@ -20,18 +20,19 @@
 package org.apache.ranger.plugin.resourcematcher;
 
 
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import java.util.Map;
+
 
 public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher {
 	private static final Log LOG = LogFactory.getLog(RangerDefaultResourceMatcher.class);
 
 	@Override
-	public boolean isMatch(String resource) {
+	public boolean isMatch(String resource, Map<String, Object> evalContext) {
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + resource + ")");
+			LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + resource + ", " + evalContext + ")");
 		}
 
 		boolean ret = false;
@@ -40,14 +41,13 @@ public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher
 		if(allValuesRequested || isMatchAny) {
 			ret = isMatchAny;
 		} else {
-			if (CollectionUtils.isNotEmpty(resourceMatchers)) {
-				for (ResourceMatcher resourceMatcher : resourceMatchers) {
-					ret = resourceMatcher.isMatch(resource);
-					if (ret) {
-						break;
-					}
+			for (ResourceMatcher resourceMatcher : resourceMatchers.getResourceMatchers()) {
+				ret = resourceMatcher.isMatch(resource, evalContext);
+				if (ret) {
+					break;
 				}
 			}
+
 		}
 
 		ret = applyExcludes(allValuesRequested, ret);
@@ -67,7 +67,7 @@ public class RangerDefaultResourceMatcher extends RangerAbstractResourceMatcher
 		}
 
 		if(LOG.isDebugEnabled()) {
-			LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + resource + "): " + ret);
+			LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + resource + ", " + evalContext + "): " + ret);
 		}
 
 		return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
index d508f3f..fec527f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
@@ -19,16 +19,19 @@
 
 package org.apache.ranger.plugin.resourcematcher;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOCase;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 
 public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
@@ -46,8 +49,10 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 			LOG.debug("==> RangerPathResourceMatcher.init()");
 		}
 
+		Map<String, String> options = resourceDef == null ? null : resourceDef.getMatcherOptions();
+
 		policyIsRecursive = policyResource == null ? false : policyResource.getIsRecursive();
-		pathSeparatorChar = getCharOption(OPTION_PATH_SEPARATOR, DEFAULT_PATH_SEPARATOR_CHAR);
+		pathSeparatorChar = ServiceDefUtil.getCharOption(options, OPTION_PATH_SEPARATOR, DEFAULT_PATH_SEPARATOR_CHAR);
 
 		super.init();
 
@@ -57,8 +62,10 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 	}
 
 	@Override
-	protected List<ResourceMatcher> buildResourceMatchers() {
-		List<ResourceMatcher> ret = new ArrayList<ResourceMatcher>();
+
+	protected ResourceMatcherWrapper buildResourceMatchers() {
+		List<ResourceMatcher> resourceMatchers = new ArrayList<ResourceMatcher>();
+		boolean needsDynamicEval = false;
 
 		for (String policyValue : policyValues) {
 			if (optWildCard && policyIsRecursive) {
@@ -71,17 +78,20 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 
 			if (matcher != null) {
 				if (matcher.isMatchAny()) {
-					ret.clear();
+					resourceMatchers.clear();
 					break;
-				} else {
-					ret.add(matcher);
 				}
+				if (!needsDynamicEval && matcher.getNeedsDynamicEval()) {
+					needsDynamicEval = true;
+				}
+				resourceMatchers.add(matcher);
 			}
 		}
 
-		Collections.sort(ret);
+		Collections.sort(resourceMatchers);
 
-		return ret;
+		return CollectionUtils.isNotEmpty(resourceMatchers) ?
+				new ResourceMatcherWrapper(needsDynamicEval, resourceMatchers) : null;
 	}
 
 	@Override
@@ -118,6 +128,8 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 			ret = optIgnoreCase ? new CaseInsensitiveStartsWithMatcher(policyValue) : new CaseSensitiveStartsWithMatcher(policyValue);
 		}
 
+		ret.setDelimiters(startDelimiterChar, endDelimiterChar, escapeChar, tokenPrefix);
+
 		return ret;
 	}
 
@@ -152,7 +164,6 @@ public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 				ret = FilenameUtils.wildcardMatch(pathToCheck, wildcardPath, caseSensitivity) ;
 			}
 		}
-
 		return ret;
 	}
 
@@ -177,10 +188,11 @@ final class CaseSensitiveRecursiveWildcardMatcher extends ResourceMatcher {
 		this.levelSeparatorChar = levelSeparatorChar;
 	}
 
-	boolean isMatch(String str) {
-		return RangerPathResourceMatcher.isRecursiveWildCardMatch(str, value, levelSeparatorChar, IOCase.SENSITIVE);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return RangerPathResourceMatcher.isRecursiveWildCardMatch(resourceValue, getExpandedValue(evalContext), levelSeparatorChar, IOCase.SENSITIVE);
 	}
-	int getPriority() { return 7;}
+	int getPriority() { return 7 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveRecursiveWildcardMatcher extends ResourceMatcher {
@@ -190,10 +202,10 @@ final class CaseInsensitiveRecursiveWildcardMatcher extends ResourceMatcher {
 		this.levelSeparatorChar = levelSeparatorChar;
 	}
 
-	boolean isMatch(String str) {
-		return RangerPathResourceMatcher.isRecursiveWildCardMatch(str, value, levelSeparatorChar, IOCase.INSENSITIVE);
+	@Override
+	boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+		return RangerPathResourceMatcher.isRecursiveWildCardMatch(resourceValue, getExpandedValue(evalContext), levelSeparatorChar, IOCase.INSENSITIVE);
 	}
-	int getPriority() { return 8;}
+	int getPriority() { return 8 + (getNeedsDynamicEval() ? DYNAMIC_EVALUATION_PENALTY : 0);}
 
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
index 8f1cebe..c1d8366 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
@@ -22,6 +22,8 @@ package org.apache.ranger.plugin.resourcematcher;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 
+import java.util.Map;
+
 public interface RangerResourceMatcher {
 	void setResourceDef(RangerResourceDef resourceDef);
 
@@ -31,8 +33,10 @@ public interface RangerResourceMatcher {
 
 	boolean isMatchAny();
 
-	boolean isMatch(String resource);
+	boolean isMatch(String resource, Map<String, Object> evalContext);
+
+	boolean isCompleteMatch(String resource, Map<String, Object> evalContext);
 
-	boolean isCompleteMatch(String resource);
+	boolean getNeedsDynamicEval();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
index 39eb339..853c525 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
@@ -19,16 +19,31 @@
 
 package org.apache.ranger.plugin.resourcematcher;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.util.StringTokenReplacer;
+
+import java.util.Map;
+
 abstract class ResourceMatcher implements Comparable<ResourceMatcher> {
+    private static final Log LOG = LogFactory.getLog(ResourceMatcher.class);
+
     protected final String value;
+    protected StringTokenReplacer tokenReplacer;
+
+    static final int DYNAMIC_EVALUATION_PENALTY = 8;
 
     ResourceMatcher(String value) { this.value = value; }
 
-    abstract boolean isMatch(String str);
+    abstract boolean isMatch(String resourceValue, Map<String, Object> evalContext);
     abstract int getPriority();
 
     boolean isMatchAny() { return value != null && value.length() == 0; }
 
+    boolean getNeedsDynamicEval() {
+        return tokenReplacer != null;
+    }
+
     @Override
     public int compareTo(ResourceMatcher other) { return Integer.compare(getPriority(), other.getPriority()); }
 
@@ -36,4 +51,32 @@ abstract class ResourceMatcher implements Comparable<ResourceMatcher> {
     public String toString() {
         return this.getClass().getName() + "(" + this.value + ")";
     }
-}
\ No newline at end of file
+
+    void setDelimiters(char startDelimiterChar, char endDelimiterChar, char escapeChar, String tokenPrefix) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> setDelimiters(value= " + value + ", startDelimiter=" + startDelimiterChar +
+                    ", endDelimiter=" + endDelimiterChar + ", escapeChar=" + escapeChar + ", prefix=" + tokenPrefix);
+        }
+
+        if(value != null && (value.indexOf(escapeChar) != -1 || (value.indexOf(startDelimiterChar) != -1 && value.indexOf(endDelimiterChar) != -1))) {
+            tokenReplacer = new StringTokenReplacer(startDelimiterChar, endDelimiterChar, escapeChar, tokenPrefix);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== setDelimiters(value= " + value + ", startDelimiter=" + startDelimiterChar +
+                    ", endDelimiter=" + endDelimiterChar + ", escapeChar=" + escapeChar + ", prefix=" + tokenPrefix);
+        }
+    }
+
+    String getExpandedValue(Map<String, Object> evalContext) {
+        final String ret;
+
+        if(tokenReplacer != null) {
+            ret = tokenReplacer.replaceTokens(value, evalContext);
+        } else {
+            ret = value;
+        }
+
+        return ret;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
index 0ce3721..2f3a39e 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
@@ -37,6 +37,8 @@ public class RangerAccessRequestUtil {
 	public static final String KEY_CONTEXT_TAG_OBJECT          = "TAG_OBJECT";
 	public static final String KEY_CONTEXT_RESOURCE            = "RESOURCE";
 	public static final String KEY_CONTEXT_REQUESTED_RESOURCES = "REQUESTED_RESOURCES";
+	public static final String KEY_TOKEN_NAMESPACE = "token:";
+	public static final String KEY_USER = "USER";
 
 	public static void setRequestTagsInContext(Map<String, Object> context, List<RangerTag> tags) {
 		if(CollectionUtils.isEmpty(tags)) {
@@ -125,4 +127,22 @@ public class RangerAccessRequestUtil {
 
 		return ret;
 	}
+
+	public static void setCurrentUserInContext(Map<String, Object> context, String user) {
+		setTokenInContext(context, KEY_USER, user);
+	}
+
+	public static String getCurrentUserFromContext(Map<String, Object> context) {
+		Object ret = getTokenFromContext(context, KEY_USER);
+		return ret != null ? ret.toString() : "";
+	}
+
+	public static void setTokenInContext(Map<String, Object> context, String tokenName, Object tokenValue) {
+		String tokenNameWithNamespace = KEY_TOKEN_NAMESPACE + tokenName;
+		context.put(tokenNameWithNamespace, tokenValue);
+	}
+	public static Object getTokenFromContext(Map<String, Object> context, String tokenName) {
+		String tokenNameWithNamespace = KEY_TOKEN_NAMESPACE + tokenName;
+		return MapUtils.isNotEmpty(context) ? context.get(tokenNameWithNamespace) : null;
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
index 0f10deb..cb3b84a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
@@ -31,6 +31,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @JsonAutoDetect(getterVisibility= JsonAutoDetect.Visibility.NONE, setterVisibility= JsonAutoDetect.Visibility.NONE, fieldVisibility= JsonAutoDetect.Visibility.ANY)
 @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL )
@@ -67,7 +68,7 @@ public class RangerRequestedResources {
 		}
 	}
 
-	public boolean isMutuallyExcluded(final List<RangerPolicyResourceMatcher> matchers) {
+	public boolean isMutuallyExcluded(final List<RangerPolicyResourceMatcher> matchers, final Map<String, Object> evalContext) {
 		boolean ret = true;
 
 		int matchedCount = 0;
@@ -78,7 +79,7 @@ public class RangerRequestedResources {
 
 				for (RangerPolicyResourceMatcher matcher : matchers) {
 
-					if (matcher.isMatch(resource) && matchedCount++ > 0) {
+					if (matcher.isMatch(resource, evalContext) && matchedCount++ > 0) {
 						ret = false;
 						break;
 					}