XACML Authorization in WSO2 EI

Thishani Lucas
Think Integration
Published in
2 min readMay 14, 2019

EI uses entitlement mediator for XACML authorization. This post illustrates the usage of the entitlement mediator with WSO2 Identity Server (WSO2 IS) as the XACML Policy Decision Point (PDP).

First, lets create and publish a simple XACML policy in the WSO2 IS. I have created a simple policy securing the resource ‘/services/testProxy’ and this resource can be accessed only by the admin user.

Following is the complete policy.

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="APolicy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
<Target>
<AnyOf>
<AllOf>
<Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">/services/testProxy</AttributeValue>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</Match>
</AllOf>
</AnyOf>
</Target>
<Rule Effect="Permit" RuleId="Rule-1">
<Condition>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of">
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag">
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">write</AttributeValue>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">delete</AttributeValue>
</Apply>
<AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</Apply>
<Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:any-of">
<Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/>
<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue>
<AttributeDesignator AttributeId="http://wso2.org/claims/role" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
</Apply>
</Apply>
</Condition>
</Rule>
<Rule Effect="Deny" RuleId="Deny-Rule"/>
</Policy>

Now in the EI, lets create a proxy service named ‘testProxy’ like below.

<proxy xmlns="http://ws.apache.org/ns/synapse"
name="testProxy"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<entitlementService callbackClass="org.wso2.carbon.identity.entitlement.mediator.callback.UTEntitlementCallbackHandler"
client="basicAuth"
remoteServicePassword="enc:eyJjIjoiQko3Ylp6Qlo0YjV6dlF2YmJvZ3lmdkFzYS82SEY5TGdLcDF4TTBwWEwyM0o5S0djczJPMldPa3pnSmVZdDlhTmFPQUJkTmFMOEtTbEFIenpoVGJIRUJjVk5UeUIyUEVuSUwvZGVVOEs4T1J1amcxbEdtazF1OHhHUDNQNzRQSERBRXlCNkhVZDEvVUdqckNMZ1lqWTZKRTZ6aytsek1JY3BBYmZ5M2JjWkx2dnBmM25PbWpwTWVueUpZVitVa1JBTS9zK3IzZXh2YngrdSs5QTA4LzNIdDBzaTNlZlVweVNUM3NEakprWGZGVkFNM3E2UE9iaG1nd202aWFQLzViQmhrWCt6cWkvUTdqdzFOSVo2cld5Y1Nocm1ydzRETys4aTFTKyt2OWZQS0VkVnViSWxJdUZFWHhuOVl4NmhORGhqV3dQWjY0VC9vQ1plQTFCWVU0Lzl3XHUwMDNkXHUwMDNkIiwidCI6IlJTQS9FQ0IvT0FFUHdpdGhTSEExYW5kTUdGMVBhZGRpbmciLCJ0cCI6IjUwMUZDMTQzMkQ4NzE1NURDNDMxMzgyQUVCODQzRUQ1NThBRDYxQjEiLCJ0cGQiOiJTSEEtMSJ9"
remoteServiceUrl="https://localhost:9443/services"
remoteServiceUserName="admin">
<onReject>
<log>
<property name="ENTITLEMENT" value="REJECTED"/>
</log>
</onReject>
<onAccept>
<log>
<property name="ENTITLEMENT" value="ACCEPTED"/>
</log>
<call>
<endpoint>
<address uri="http://www.mocky.io/v2/5185415ba171ea3a00704eed"/>
</endpoint>
</call>
<property name="messageType" scope="axis2" value="text/xml"/>
</onAccept>
<obligations/>
<advice/>
</entitlementService>
<respond/>
</inSequence>
<outSequence/>
</target>
<enableSec/>
<policy key="gov:datamapper/SmaplePolicy.xml"/>
<description/>
</proxy>

Here we have used an entitlement mediator where the remoteServiceUrl is the URL of the WSO2 IS. IS will decide if the request is authorized and if yes, the onAccept sequence will be executed.

Please note that we have secured the proxy service using a Username token policy. That’s why I have used UTEntitlementCallbackHandler as the call back class in the entitlement mediator.

Now if we call the proxy, we can see a response similar to the following and the log ‘ENTITLEMENT = ACCEPTED’ printed.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsu:Timestamp wsu:Id="Timestamp-3" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2019-05-14T09:17:21.869Z</wsu:Created>
<wsu:Expires>2019-05-14T09:22:21.869Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<jsonObject>
<hello>world</hello>
</jsonObject>
</soapenv:Body>
</soapenv:Envelope>

That’s all for this blog. Stay tuned for the next one!

Further readings:

--

--