After checking out the k-market sample from balana (http://svn.wso2.org/repos/wso2/trunk/commons/balana/modules/balana-samples/kmarket-trading-sample/) i wanted to create a similar sample project. I have created the following 2 classes. The balana source was downloaded from the same trunk.
public class Test {
public static void main(String[] args) throws JDOMException, IOException, SAXException, URISyntaxException {
//Create the xacml request as a string
Document xacmlRequest = createXACMLRequest();
String requestString = writeRequestToString(xacmlRequest);
//Specify XACML Policies Directory
//System.setProperty(ConfigurationStore.PDP_CONFIG_PROPERTY, "Config/config.xml");
System.setProperty(FileBasedPolicyFinderModule.POLICY_DIR_PROPERTY, "Policies");
Balana balana = Balana.getInstance();
PDPConfig pdpConfig = balana.getPdpConfig();
//Keep ONLY my SampleAttributeFinderModule for testing purposes
AttributeFinder attributeFinder = pdpConfig.getAttributeFinder();
//List<AttributeFinderModule> modules = attributeFinder.getModules();
List<AttributeFinderModule> modules = new ArrayList<AttributeFinderModule>();
modules.add(new SampleAttributeFinderModule());
attributeFinder.setModules(modules);
PDPConfig newPDPConfig = new PDPConfig(attributeFinder, pdpConfig.getPolicyFinder(), pdpConfig.getResourceFinder(), false);
PDP pdp = new PDP(newPDPConfig);
System.out.println(pdp.evaluate(requestString));
}
and
public class SampleAttributeFinderModule extends AttributeFinderModule {
@Override
public boolean isDesignatorSupported() {
return true;
}
@Override
public Set<String> getSupportedCategories() {
Set<String> categories = new HashSet<String>();
categories.add("urn:oasis:names:tc:xacml:3.0:attribute-category:resource");
return categories;
}
@Override
public Set getSupportedIds() {
Set<String> ids = new HashSet<String>();
ids.add("http://wso2.org/claims/emailaddress");
return ids;
}
@Override
public EvaluationResult findAttribute(URI attributeType, URI attributeId, String issuer,
URI category, EvaluationCtx context) {
System.out.println("Custom Attribute Finder initiated");
List<AttributeValue> attributeValues = new ArrayList<AttributeValue>();
//Just return the same value, for test purposes
attributeValues.add(new StringAttribute("Tom"));
return new EvaluationResult(new BagAttribute(attributeType, attributeValues));
}
While i think the above code should work , my SampleAttributeFinderModule is never called, and the evaluation only succeeds if my request contains the specified attribute. My Policy is this :
<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17 http://docs.oasis-open.org/xacml/3.0/xacml-core-v3-schema-wd-17.xsd"
Version="1.0"
PolicyId="SamplePolicy"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides">
<Target/>
<!-- Rule to see if we should allow the Subject to login -->
<Rule RuleId="LoginRule" Effect="Permit">
<Target/>
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
<AttributeDesignator
AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only">
<AttributeDesignator
AttributeId="http://wso2.org/claims/emailaddress"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:resource"
DataType="http://www.w3.org/2001/XMLSchema#string"
MustBePresent="true"/>
</Apply>
</Apply>
</Condition>
</Rule>
<!-- We could include other Rules for different actions here -->
<!-- A final, "fall-through" Rule that always Denies -->
<Rule RuleId="FinalRule" Effect="Deny"/>
</Policy>
Any help would be appreciated. Note that, after looking at the balana source , and after tracking how it's methods are called, i stumbled upon the following piece of code (im sure this is called when i run the program). It seems like it first tries to get the attributes from the request, but the first if always evaluates to false if the attributeis not in the request (i think), so the callHelper method which contains the modules is never called. Is this intended?
package org.wso2.balana.ctx.xacml3;
public class XACML3EvaluationCtx extends BasicEvaluationCtx {
// other methods
public EvaluationResult getAttribute(URI type, URI id, String issuer, URI category) {
List<AttributeValue> attributeValues = new ArrayList<AttributeValue>();
Set<Attributes> attributesSet = mapAttributes.get(category.toString());
if(attributesSet != null && attributesSet.size() > 0){
Set<Attribute> attributeSet = attributesSet.iterator().next().getAttributes();
for(Attribute attribute : attributeSet) {
if(attribute.getId().equals(id) && attribute.getType().equals(type)
&& (issuer == null || issuer.equals(attribute.getIssuer()))
&& attribute.getValue() != null){
List<AttributeValue> attributeValueList = attribute.getValues();
for (AttributeValue attributeVal : attributeValueList) {
attributeValues.add(attributeVal);
}
}
}
if(attributeValues.size() < 1){
return callHelper(type, id, issuer, category);
}
}
//If i put this piece of code here instead of up there (outside the first if) , it works as i want to
/*if(attributeValues.size() < 1){
return callHelper(type, id, issuer, category);
}*/
// if we got here, then we found at least one useful AttributeValue
return new EvaluationResult(new BagAttribute(type, attributeValues));
}