Multi-value comparisons in XACML
There's a bit of a mismatch in the XACML specification, in that most of the functions operate on single arguments but attributes are always returned in bags. This is fine when comparing values in the <SubjectMatch> (and similar) elements as the multi-valued nature of the four AttributeDesignator elements is handled automatically; comparing values in the <Condition> requires a little more effort.
Luckily there are two classes of functions that allow comparison between a single value and bags of values, or between two bags of values.
Comparing a single value to a bag of values
For example, let's say we need to check of the attribute "department" is equal to "Finance". You could do a simple string-equality check as follows:
<Apply FunctionId="string-equal">
<AttributeValue DataType="#string">Finance</AttributeValue>
<SubjectAttributeDesignator AttributeId="department" DataType="#string" />
</Apply>
This is well and good until the "department" attribute is multi-valued. In that case, the "string-equal" function will try to compare a string to a bag of strings and fail with either a syntax error or processing error.
There are a two functions to help here, "any-of" and "all-of". Both are boolean functions that allow a constant to be compared to a bag of values, with "any-of" returning true if one of the bag members causes a match and "all-of" returning true if all of the bag members return a match.
Our example above can be re-written as:
<code><Apply FunctionId="any-of">
<Function FunctionId="string-equal"/>
<AttributeValue DataType="#string">Finance</AttributeValue>
<SubjectAttributeDesignator
AttributeId="department" DataType="#string" />
</Apply>
The "string-equal" function is applied to "Finance" and each attribute returned from the <SubjectAttributeDesignator>. If any of these comparisons returns true, then the result of the "any-of" function is also true.
Comparing a bag of values to a bag of values
What if we needed to see if the "department" field was in a range of possible values, such as "Finance" OR "Human Resources"? Using the "any-of" function would fail for the same reasons the original "string-equal" function failed, as a bag of values would be in the place where a single value was expected.
We can use functions such as "any-of-any" to solve this requirement. "Any-of-any" applies a function between each element of two bags of values, returning true if at least one of these comparisons returns true. Our example can be expressed as:
<Apply FunctionId="any-of-any">
<Function FunctionId="string-equal"/>
<Apply FunctionId="string-bag">
<AttributeValue DataType="#string">Finance</AttributeValue>
<AttributeValue DataType="#string">Human Resources</AttributeValue>
</Apply>
<SubjectAttributeDesignator
AttributeId="department" DataType="#string" />
</Apply>
Notice that I've also used the "string-bag" function to convert a list of <AttributeValue> elements to a bag suitable for consumption by this function.
blog comments powered by Disqus