Forum Discussion
You wouldn't be able to use the built-in xpath query engine because that's tied to an XML profile and the XML_CONTENT_BASED_ROUTING event, which only works in an HTTP/XML request context. You could, technically, grab the entire XML payload and send it via sideband call to another VIP that can do the xpath processing, but I think the following might be just as efficient:
when ACCESS_POLICY_COMPLETED {
grab the entire AttributeStatements section
set attr_statement [findstr [ACCESS::session data get session.saml.last.assertion] "" 26 ""]
create an empty list
set attr_list [list]
split the attributes and loop through them
foreach x [split $attr_statement "<"] {
if { $x starts_with "saml2:Attribute Name=" } {
found an attribute name - add it to the list
lappend attr_list [findstr $x "saml2:Attribute Name=\"" 22 "\""]
} elseif { $x starts_with "saml2:AttributeValue>" } {
found an attribute value - add it to the list
lappend attr_list [findstr $x "saml2:AttributeValue>" 21 "<"]
}
}
result is a list. Ex. [name1 value1 name2 value2 name3 value3]
log local0. $attr_list
}
So if you're doing this with an APM IdP assertion, the assertion attributes are between the "" and "" elements. So I grab that value from session.saml.last.assertion, split the remaining content on the "<" character, and then loop through the new list. I then build a list with all of the names and values, example:
[name1 value1 name2 value2 name3 value3 name4 value4]
As a list object, you can then perform all sorts of really cool operations on it - count, search, etc. to get whatever information you want:
log local0. "Total number of attributes: [expr [llength $attr_list] / 2]"
for { set i 0 } { $i < [llength $attr_list] } { incr i 2 } {
log local0. "[lindex $attr_list $i] = [lindex $attr_list [expr $i + 1]]"
}
or if I wanted to grab a specific value (ex. the 'state' attribute):
set state_attr [lindex $attr_list [expr [lsearch $attr_list "state"] + 1]]
log local0. "The 'state' attribute: $state_attr"
and optionally check to make sure the index value returned from the lsearch command is an even number, or zero (0,2,4,6,etc), so you're sure it's a name attribute.