在检查了balana(http://svn.wso2.org/repos/wso2/trunk/commons/balana/modules/balana-samples/kmarket-trading-sample/)的k-market样本后,我想创建一个类似的示例项目。我创建了以下2个类。 balana源是从同一个主干下载的。
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));
}
和
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));
}
虽然我认为上面的代码应该可行,但我的SampleAttributeFinderModule永远不会被调用,只有当我的请求包含指定的属性时,评估才会成功。我的政策是:
<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>
任何帮助将不胜感激。注意,在查看balana源之后,在跟踪它的方法被调用之后,我偶然发现了下面的一段代码(我确定在运行程序时会调用它)。它似乎首先尝试从请求中获取属性,但如果属性不在请求中(我认为),则第一个if总是求值为false,因此永远不会调用包含模块的callHelper方法。这是为了吗?
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));
}