Writing an XACML 3.0 Policy Using XPath
XPath is a major element in the XSLT standard and it is a syntax for defining parts of an XML document. XPath can be used to navigate through elements and attributes in an XML document.
XPath is playing an import role in XACML when policies are evaluated for XML based data. When XML data is passed across nodes, PEP can be an interception point that calls the PDP with parsing XML data. Based on the XML data, PDP can take decisions. Let see how we can develop a simple policy that can be used to evaluate an XML data.
Here we are taking this sample scenario for this
- There is Medicom healthcare application where the online registered user (patient, doctors and so on) can examine patient data.
- Patient data store returns any data that is requested for given patient id, regardless of the login user to the application.
- Medicom has authorization interceptor (PEP) between their web application and patient data store. PEP would authorize the requested data by calling to a PDP.
- One authorization rule is “Users can only read their own patient data”
Let's write an XACML policy for this.
According to our user-case, it says “User can only read their own patient data”. Eg: if you log in to the Medicom web application with patient id “Larry” then you can only read patient data that is store for “Larry”.
Below code will show a sample policy which is written to match the resources relevant to a specific patientId.
Here, the XPath evaluation is done with respect to content elementand check for a matching value and the content element has been bounded with custom namespace and prefix eg:Path="//ak:record/ak:patient/ak:patientId/text()"
<?xml version="1.0" encoding="UTF-8"?> <Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="medi-xpath-test-policy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0"> <Description>XPath evaluation is done with respect to content elementand check for a matching value. Here content element has been bounded with custom namespace and prefix</Description> <PolicyDefaults> <XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</XPathVersion> </PolicyDefaults> <Target> <AnyOf> <AllOf> <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> <AttributeDesignator MustBePresent="false" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" /> </Match> </AllOf> </AnyOf> </Target> <Rule RuleId="rule1" Effect="Permit"> <Description>Rule to match value in content element using XPath</Description> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of"> <Function 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 Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false" /> </Apply> <AttributeSelector MustBePresent="false" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" Path="//ak:record/ak:patient/ak:patientId/text()" DataType="http://www.w3.org/2001/XMLSchema#string" /> </Apply> </Condition> </Rule> <Rule RuleId="rule2" Effect="Deny"> <Description>Deny rule</Description> </Rule> </Policy>
Deploy and publish the policy:
- Start WSO2 Identity Server and Log in to the management console.
- Go to Policy Administration under PAP in Main and Click on Add New Entitlement Policy.
- Next Click on Import Existing Policy.
- Save the above sample policy to a file and import it as follows by clicking "upload".
- Once it is uploaded, you can see the added policy in the policy view. Publish it to PDP so that we can evaluate that policy with sample requests.
Evaluate the Policy:
For this, the easiest way is to use the Try It tool available in our Tools menu in WSO2 Identity Server.
You can follow the following steps in here to try this using Try It tool.
Sample Request | <?xml version="1.0" encoding="UTF-8"?> <Request xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" ReturnPolicyIdList="false" CombinedDecision="false"> <Attributes Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"> <Attribute IncludeInResult="false" AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">Larry</AttributeValue> </Attribute> </Attributes> <Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"> <Content> <ak:record xmlns:ak="http://akpower.org"> <ak:patient> <ak:patientId>Larry</ak:patientId> <ak:patientName> <ak:first>Larry</ak:first> <ak:last>Allan</ak:last> </ak:patientName> <ak:patientContact> <ak:street>51 Main road</ak:street> <ak:city>Colombo</ak:city> <ak:state>Western</ak:state> <ak:zip>11730</ak:zip> <ak:phone>94332189873</ak:phone> <ak:email>Larry@wso2.com</ak:email> </ak:patientContact> <ak:patientDoB>1991-05-11</ak:patientDoB> <ak:patientGender>male</ak:patientGender> </ak:patient> </ak:record> </Content> </Attributes> <Attributes Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action"> <Attribute IncludeInResult="false" AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> </Attribute> </Attributes> </Request> |
---|---|
Sample Response | <?xml version="1.0" encoding="UTF-8"?> <Response> <Result> <Decision>Permit</Decision> <Status> <StatusCode Value="urn:oasis:names:tc:xacml:1.0:status:ok" /> </Status> </Result> </Response> |