Author: sohil.shah(a)jboss.com
Date: 2009-02-05 15:54:56 -0500 (Thu, 05 Feb 2009)
New Revision: 12782
Modified:
modules/authorization/trunk/core-components/src/main/java/org/jboss/security/authz/components/http/HttpResource.java
modules/authorization/trunk/core-components/src/test/java/org/jboss/security/authz/components/http/TestHttpResourceRules.java
modules/authorization/trunk/policy-server/src/main/java/org/jboss/security/authz/policy/server/plugin/DroolsFunction.java
modules/authorization/trunk/policy-server/src/test/java/org/jboss/security/authz/policy/server/plugin/TestEnterprisePolicyFinderModule.java
Log:
Integrating Drools based Expressions to specify Policy Rules for the HttpResource core
component
* Actual Rule specified in DRL format and works end-to-end
Modified:
modules/authorization/trunk/core-components/src/main/java/org/jboss/security/authz/components/http/HttpResource.java
===================================================================
---
modules/authorization/trunk/core-components/src/main/java/org/jboss/security/authz/components/http/HttpResource.java 2009-02-05
19:40:08 UTC (rev 12781)
+++
modules/authorization/trunk/core-components/src/main/java/org/jboss/security/authz/components/http/HttpResource.java 2009-02-05
20:54:56 UTC (rev 12782)
@@ -26,6 +26,7 @@
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
+import java.text.MessageFormat;
import org.jboss.security.authz.model.AttributeExpression;
import org.jboss.security.authz.model.Effect;
@@ -54,21 +55,27 @@
{
//make it package-level access so that unit tests can test these rules
static final String allowedRolesRule =
+ "import java.util.HashSet\n"+
"rule \"allowedRolesRule\"\n"+
"when\n"+
"$ruleName: String()\n"+
+ "$roles: HashSet()\n"+
"eval($ruleName.contains(\"httpResource://permittedRoles\"))\n"+
+ "eval({0})\n"+
"then\n"+
- "System.out.println(\"AllowedRolesRule successfully
fired\");\n"+
+ "insert(Boolean.TRUE);\n"+
"end\n";
- static final String deniedRolesRule =
+ static final String deniedRolesRule =
+ "import java.util.HashSet\n"+
"rule \"deniedRolesRule\"\n"+
"when\n"+
"$ruleName: String()\n"+
+ "$roles: HashSet()\n"+
"eval($ruleName.contains(\"httpResource://deniedRoles\"))\n"+
+ "eval({0})\n"+
"then\n"+
- "System.out.println(\"DeniedRolesRule successfully
fired\");\n"+
+ "insert(Boolean.TRUE);\n"+
"end\n";
static final String allowedIpsRule =
@@ -77,7 +84,7 @@
"$ruleName: String()\n"+
"eval($ruleName.contains(\"httpResource://allowedIps\"))\n"+
"then\n"+
- "System.out.println(\"AllowedIpsRule successfully
fired\");\n"+
+ "insert(Boolean.TRUE);\n"+
"end\n";
/**
@@ -250,14 +257,19 @@
permitRule.setRuleId(ruleReference);
permitRule.setEffect(Effect.PERMIT);
- //Generate a Drools Rule
+ //Generate a Drools Rule Expression
+ StringBuffer buffer = new StringBuffer();
for(String role: this.allowedRoles)
{
+ buffer.append("$roles.contains(\""+role.toLowerCase()+"\")
|| ");
}
+ String condition = buffer.toString().trim();
+ String rule = MessageFormat.format(HttpResource.allowedRolesRule,
+ new Object[]{condition.substring(0, condition.length()-2).trim()});
DroolsRuleExpression expression = new DroolsRuleExpression();
expression.setRuleReference(ruleReference);
- expression.setRule(HttpResource.allowedRolesRule);
+ expression.setRule(rule);
permitRule.setExpression(expression);
return permitRule;
@@ -281,13 +293,19 @@
denyRule.setRuleId(ruleReference);
denyRule.setEffect(Effect.DENY);
- //Generate a Drools Rule
+ //Generate a Drools Rule Expression
+ StringBuffer buffer = new StringBuffer();
for(String role: this.deniedRoles)
- {
+ {
+ buffer.append("$roles.contains(\""+role.toLowerCase()+"\")
|| ");
}
+ String condition = buffer.toString().trim();
+ String rule = MessageFormat.format(HttpResource.deniedRolesRule,
+ new Object[]{condition.substring(0, condition.length()-2).trim()});
+
DroolsRuleExpression expression = new DroolsRuleExpression();
expression.setRuleReference(ruleReference);
- expression.setRule(HttpResource.deniedRolesRule);
+ expression.setRule(rule);
denyRule.setExpression(expression);
return denyRule;
@@ -306,6 +324,7 @@
rule.setRuleId(ruleReference);
rule.setEffect(Effect.PERMIT);
+ //TODO: Generate a Drools Rule Expression
for(String allowedIp: this.allowedIps)
{
/*AttributeExpression expression = new AttributeExpression();
@@ -316,6 +335,7 @@
rule.setExpression(expression);*/
}
+
DroolsRuleExpression expression = new DroolsRuleExpression();
expression.setRuleReference(ruleReference);
expression.setRule(HttpResource.allowedIpsRule);
Modified:
modules/authorization/trunk/core-components/src/test/java/org/jboss/security/authz/components/http/TestHttpResourceRules.java
===================================================================
---
modules/authorization/trunk/core-components/src/test/java/org/jboss/security/authz/components/http/TestHttpResourceRules.java 2009-02-05
19:40:08 UTC (rev 12781)
+++
modules/authorization/trunk/core-components/src/test/java/org/jboss/security/authz/components/http/TestHttpResourceRules.java 2009-02-05
20:54:56 UTC (rev 12782)
@@ -24,6 +24,10 @@
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.text.MessageFormat;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
import junit.framework.TestCase;
@@ -56,8 +60,8 @@
StringBuilder buffer = new StringBuilder();
buffer.append(rulePkg+"\n");
- buffer.append(HttpResource.allowedRolesRule+"\n");
- buffer.append(HttpResource.deniedRolesRule+"\n");
+ buffer.append(this.getAllowedRolesRule()+"\n");
+ buffer.append(this.getDeniedRolesRule()+"\n");
buffer.append(HttpResource.allowedIpsRule+"\n");
Reader source = new InputStreamReader(new
ByteArrayInputStream(buffer.toString().getBytes()));
@@ -91,18 +95,61 @@
{
log.info("Executing----------testAllowedRolesRule");
WorkingMemory workingMemory = this.activeRuleBase.newStatefulSession();
+
+ //SetUp the context data
workingMemory.insert("httpResource://permittedRoles/"+GeneralTool.generateUniqueId());
+ Set roles = new HashSet();
+ roles.add("admin");
+ roles.add("superuser");
+ workingMemory.insert(roles);
+
workingMemory.fireAllRules();
+
+ //Extract result
+ boolean success = false;
+ Iterator itr = workingMemory.iterateObjects();
+ while(itr.hasNext())
+ {
+ Object curr = itr.next();
+ if(curr instanceof Boolean)
+ {
+ success = ((Boolean)curr).booleanValue();
+ }
+ }
+
((StatefulSession)workingMemory).dispose();
+
+ assertTrue("Rule did not execute!!", success);
}
public void testDeniedRolesRule() throws Exception
{
log.info("Executing----------testDeniedRolesRule");
WorkingMemory workingMemory = this.activeRuleBase.newStatefulSession();
+
+ //SetUp the context data
workingMemory.insert("httpResource://deniedRoles/"+GeneralTool.generateUniqueId());
+ Set roles = new HashSet();
+ roles.add("anonymous");
+ workingMemory.insert(roles);
+
workingMemory.fireAllRules();
+
+ //Extract result
+ boolean success = false;
+ Iterator itr = workingMemory.iterateObjects();
+ while(itr.hasNext())
+ {
+ Object curr = itr.next();
+ if(curr instanceof Boolean)
+ {
+ success = ((Boolean)curr).booleanValue();
+ }
+ }
+
((StatefulSession)workingMemory).dispose();
+
+ assertTrue("Rule did not execute!!", success);
}
public void testAllowedIpsRule() throws Exception
@@ -111,6 +158,53 @@
WorkingMemory workingMemory = this.activeRuleBase.newStatefulSession();
workingMemory.insert("httpResource://allowedIps/"+GeneralTool.generateUniqueId());
workingMemory.fireAllRules();
+
+ //Extract result
+ boolean success = false;
+ Iterator itr = workingMemory.iterateObjects();
+ while(itr.hasNext())
+ {
+ Object curr = itr.next();
+ if(curr instanceof Boolean)
+ {
+ success = ((Boolean)curr).booleanValue();
+ }
+ }
+
((StatefulSession)workingMemory).dispose();
+
+ assertTrue("Rule did not execute!!", success);
}
+ //------------------------------------------------------------------------------------------------------------------------------------------------------
+ private String getAllowedRolesRule()
+ {
+ String[] mockRoles = new String[]{"Admin", "SupErUser"};
+
+ StringBuffer buffer = new StringBuffer();
+ for(String role: mockRoles)
+ {
+ buffer.append("$roles.contains(\""+role.toLowerCase()+"\")
|| ");
+ }
+ String condition = buffer.toString().trim();
+ String rule = MessageFormat.format(HttpResource.allowedRolesRule,
+ new Object[]{condition.substring(0, condition.length()-2).trim()});
+
+ return rule;
+ }
+
+ private String getDeniedRolesRule()
+ {
+ String[] mockRoles = new String[]{"Anonymous", "Regular"};
+
+ StringBuffer buffer = new StringBuffer();
+ for(String role: mockRoles)
+ {
+ buffer.append("$roles.contains(\""+role.toLowerCase()+"\")
|| ");
+ }
+ String condition = buffer.toString().trim();
+ String rule = MessageFormat.format(HttpResource.deniedRolesRule,
+ new Object[]{condition.substring(0, condition.length()-2).trim()});
+
+ return rule;
+ }
}
Modified:
modules/authorization/trunk/policy-server/src/main/java/org/jboss/security/authz/policy/server/plugin/DroolsFunction.java
===================================================================
---
modules/authorization/trunk/policy-server/src/main/java/org/jboss/security/authz/policy/server/plugin/DroolsFunction.java 2009-02-05
19:40:08 UTC (rev 12781)
+++
modules/authorization/trunk/policy-server/src/main/java/org/jboss/security/authz/policy/server/plugin/DroolsFunction.java 2009-02-05
20:54:56 UTC (rev 12782)
@@ -24,19 +24,28 @@
import java.util.List;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.net.URI;
import org.apache.log4j.Logger;
import org.drools.RuleBase;
import org.drools.WorkingMemory;
+import org.drools.StatefulSession;
import org.jboss.security.authz.policy.server.Server;
+import org.jboss.security.xacml.interfaces.XACMLConstants;
+import org.jboss.security.xacml.interfaces.XMLSchemaConstants;
import org.jboss.security.xacml.sunxacml.EvaluationCtx;
import org.jboss.security.xacml.sunxacml.cond.EvaluationResult;
import org.jboss.security.xacml.sunxacml.cond.FunctionBase;
import org.jboss.security.xacml.sunxacml.ctx.Status;
import org.jboss.security.xacml.sunxacml.attr.BooleanAttribute;
+import org.jboss.security.xacml.sunxacml.attr.BagAttribute;
+import org.jboss.security.xacml.sunxacml.attr.StringAttribute;
import org.jboss.security.xacml.sunxacml.cond.VariableReference;
/**
@@ -108,18 +117,38 @@
{
VariableReference reference = (VariableReference)inputs.get(i);
- log.info("Firing Rule ="+reference.getVariableId());
+ log.debug("Firing Rule ="+reference.getVariableId());
+ //Establish a Stateful Drools Session
DroolsRuleManager ruleManager =
(DroolsRuleManager)Server.lookup("/policy-server/DroolsRuleManager");
RuleBase ruleBase = ruleManager.getActiveRuleBase();
WorkingMemory workingMemory = ruleBase.newStatefulSession();
+
+ //Populate the WorkingMemory with Facts
workingMemory.insert(reference.getVariableId());
+ this.prepareWorkingMemory(workingMemory, context);
+
+
+ //Execute the Rule
workingMemory.fireAllRules();
-
- /**
- * TODO: start a Drools context and evaluate the specified Rule against the
data presented in the EvaluationContext
- */
- result = EvaluationResult.getTrueInstance();
+
+ //Process the results
+ boolean success = false;
+ Iterator itr = workingMemory.iterateObjects();
+ while(itr.hasNext())
+ {
+ Object curr = itr.next();
+ if(curr instanceof Boolean)
+ {
+ success = ((Boolean)curr).booleanValue();
+ }
+ }
+
+ //Cleanup the WorkingMemory
+ ((StatefulSession)workingMemory).dispose();
+
+
+ result = EvaluationResult.getInstance(success);
}
}
}
@@ -131,5 +160,31 @@
result = new EvaluationResult(status);
}
return result;
- }
+ }
+
+ /**
+ * TODO: make this preparation more robust injecting arbitrary Facts and then let the
RuleEngine do its thing
+ *
+ * @param context
+ */
+ private void prepareWorkingMemory(WorkingMemory workingMemory, EvaluationCtx context)
throws Exception
+ {
+ //Inject Roles
+ Set<String> roles = new HashSet<String>();
+
+ EvaluationResult roleResult = context.getSubjectAttribute(new
URI(XMLSchemaConstants.DATATYPE_STRING),
+ new URI(XACMLConstants.ATTRIBUTEID_ROLE),
+ new URI(XACMLConstants.ATTRIBUTEID_ACCESS_SUBJECT));
+
+ BagAttribute roleValues = (BagAttribute)roleResult.getAttributeValue();
+ Iterator itr = roleValues.iterator();
+ while(itr.hasNext())
+ {
+ StringAttribute str = (StringAttribute)itr.next();
+ roles.add(str.getValue().toLowerCase());
+ }
+
+
+ workingMemory.insert(roles);
+ }
}
Modified:
modules/authorization/trunk/policy-server/src/test/java/org/jboss/security/authz/policy/server/plugin/TestEnterprisePolicyFinderModule.java
===================================================================
---
modules/authorization/trunk/policy-server/src/test/java/org/jboss/security/authz/policy/server/plugin/TestEnterprisePolicyFinderModule.java 2009-02-05
19:40:08 UTC (rev 12781)
+++
modules/authorization/trunk/policy-server/src/test/java/org/jboss/security/authz/policy/server/plugin/TestEnterprisePolicyFinderModule.java 2009-02-05
20:54:56 UTC (rev 12782)
@@ -91,10 +91,10 @@
log.info(policies[0].generateXACMLPolicy());
//Send an Enforcement request that should be allowed
- this.enforce(this.createPermitRequestContext(httpResource), true);
+ this.enforce(this.createRequestContext(httpResource, true), true);
//Send an Enforcement request that should be denied
- this.enforce(this.createPermitRequestContext(httpResource), false);
+ this.enforce(this.createRequestContext(httpResource, false), false);
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------
private void enforce(RequestContext request, boolean mustBePermitted) throws Exception
@@ -125,7 +125,7 @@
log.info("-----------------------------------");
log.info("Decision="+responseContext.getDecision());
}
- private RequestContext createPermitRequestContext(HttpResource httpResource) throws
Exception
+ private RequestContext createRequestContext(HttpResource httpResource, boolean
mustBePermitted) throws Exception
{
//Create ObjectFactory
ObjectFactory objectFactory = new ObjectFactory();
@@ -143,7 +143,7 @@
subjectAttribute.setAttributeId(XACMLConstants.ATTRIBUTEID_ROLE);
subjectAttribute.setDataType(XMLSchemaConstants.DATATYPE_STRING);
AttributeValueType subjectId = objectFactory.createAttributeValueType();
- subjectId.getContent().add("Admin");
+
subjectId.getContent().add(mustBePermitted?"Admin":"Anonymous");
subjectAttribute.getAttributeValue().add(subjectId);
subject.getAttribute().add(subjectAttribute);
requestType.getSubject().add(subject);