In this blog post I am going to create XACML sample (sample XACML policies , PIP and PEP) with some real world use case.
Lets assume following use case in a Health care organization
- There is a health care organization called “Medi”
- “Medi” keeps medical records of all the patients in a database repository.
- This repository has been exposed as web service in their intranet, which is called as “MediComService”
- “MediComService” service does not contain any security (authentication and authorization) mechanism except transport level security
- Medi has deploy a simple web application where patients can view their own medical records by using Internet.
- Medi Web Application uses user name, password authentication mechanism for authenticating the patients.
- Medi keeps those patient’s attributes and credentials in a LDAP based user store.
- Not only the patients, But also physicians and some other administrative persons need to access thse patient data. As an example physicians want to read his/her patient’s data and update them. Administrators want to delete existing data or create new data for patients.
- Therefore authentication is not enough for the Medi Web application and web service, There is a need for access control or authorization mechanism in to this system
- The Simplest and the most common way is to implement a role based access control (RBAC).
- But Medi application developers identify that there would be some requirements for more complex access control logics when this web application is growing in the future. Also they want to build their authorization system as standardized, policy based, externalized and extensible manner. And do not want to hard-coded their authorization logics in to their web applications.
- Finally Medi hopes to go with XACML based authorization solution.
Current high level architecture diagram of the Medi Com use case would be like following.
1. End User (Patient, Physician and so on) login to the Web Application
2. User is authenticated with LDAP User store.
3. User access Medi Com web service and retrieve the patient data through Web Application
There are two major issue with this.
- Authentication must be externalized. (We are not going to discuss on this)
- Access control must be implemented in Web application level and Web service level and also it must be externalized.
Here access control must be added for the Medi Com web application and the Medi Com web service. As an example, When user login in to the Medi Com web application, user must see only the items that are authorized to see… Also It is needed to control the web service calls to Medi Com web service, assuming that we can not do any changes to existing web service. It means that we need to intercept the message between web application and web service to do the access control.
The main tasks for the Medi application developers is to build a XACML based authorization engine. They found that it was not easy to write a XACML engine from the scratch and so try to use an exiting implementation
Medi developers decided to try with WSO2 Identity Server as their XACML engine. due to following reasons
1. It is Open source
2. High performance XACML evaluation with caching and indexing techniques.
3. Fast PDP and PEP communication via thrift protocol (16 time faster than normal web service call)
4. PDP functionality expose as web service (secured web service) in a standard manner. Therefore Web Application can itself act as PEP.
5. Supports for pluggable PIP attribute finders.
6. PDP clustering support for high availability, failover and high performance.
Now high level architecture diagram look like as follows….
1. End User (Patient, Physician and so on) login to the Web Application
2. User is authenticated with WSO2 Identity Server.
3. Identity Server calls to underline user store (LDAP) and checks authentication of end user.
4. After successful authentication, Web application calls WSO2 Identity Server to filter out the authorized items for user.
5. PDP of WSO2 Identity server needs to look for user’s attributes to make authorization decision. Then it calls to LDAP user store using PIP module to retrieve attributes of the users.
6. Login user accesses Medi Com service to retrieve the patient data
7. Above web service calls from Medi Com web application to Medi Com service must be authorized. There must be an interceptor that reads the web service call and extracts the data and calls the WSO2 Identity Server’ s PDP.
To build this scenario, We need following three sample projects
Sample Web service
Which exposes patient’s data, that is stored in a database repository. SVN of sample project can be found from here.
This service exposes following four operations. Each patient data can be identified by unique id called “patientId” which is actually the user name of the patient,
- createData (Patient patient) : creates new patient data in the database
- updateData (Patient patient) : updates existing patient data
- deleteData (String patientId) : deletes patient data given by the id
- readData (String patientId) : reads patient data given by the id
This is a Jar service. You can deploy this service using any service hosting server. But i am using WSO2 Application server for this. Let me go through the setups.
Step 1. Download WSO2 Application server from here and Extract it in to your file system.
Step 2. If you are running WSO2 Servers in same machine. Please configure port offset values using carbon.xml file which can be found at <AS_HOME>/repository/conf directory. I have configure it as follows
<Offset>2</Offset>
Step 3. Create database repository by running this sample script file. This script has been tested with MySQL only
Step 4. Configure datasource to connect to above created database repository. You need to add new datasource configuration in to master-datasources.xml file which can be found at <AS_HOME>/repository/conf/datasources directory
Sample configuration would be as follows.
Please note : Here JNDI name (jdbc/MEDICOMDB) is important. It has been hard coded in the web service source. Therefore please do not change this name
<datasource> <name>MEDICOMDB</name> <description>The datasource used for registry and user manager</description> <jndiConfig> <name>jdbc/MEDICOMDB</name> </jndiConfig> <definition type="RDBMS"> <configuration> <url>jdbc:mysql://localhost:3306/medicomdb</url> <username>root</username> <password>asela</password> <driverClassName>com.mysql.jdbc.Driver</driverClassName> <maxActive>50</maxActive> <maxWait>60000</maxWait> <testOnBorrow>true</testOnBorrow> <validationQuery>SELECT 1</validationQuery> <validationInterval>30000</validationInterval> </configuration> </definition> </datasource>
Step 5 : Copy JDBC driver (MySQL mysql-connector-java-5.1.10-bin.jar) in to <AS_HOME>/repository/components/lib directory.
Step 6 : Start WSO2 Application server and Login to the server (default credential is admin, admin)
Step 7 : Upload Jar file in to Application Server and Create web service, You can find the proper steps using following screen shots.
Now, you are done with web service deployment. Actually this is a sample service to build our scenario. Therefore we are not much worry about it. You can access the WSDL of web service using following url. You can use web service client tool to try out (such as SOAPUI)
http://localhost:9765/services/MediComPatientService?wsdl
Setting up PDP , PIP and User Store (WSO2 Identity Server)
According to the diagram, WSO2 Identity Server is used as PDP and also Authentication server. Here we are only interesting in the PDP. You do not want to do any configurations with PDP. You can run with default configuration. However configuration file (entitlement.properties) of the PDP engne can be found at <IS_HOME>/repository/conf/security directory.
For this sample, we are hoping to use LDAP user store which is embedded with the WSO2 Identity Server. But it can be any LDAP or AD or JDBC user store. Once user store is connected with Identity Server, You can manage users and roles in the LDAP user store using Identity Server management console.
Lets try to create users and roles. Following is the sample steps to create role (LDAP Group) called “Patient” and user called “asela” and Assign user in to the “Patients” group
In this scenario, There can be three LDAP Groups (Roles) Patient, Physician and Administrator. We can create them as above and assign desired users to above groups.
WSO2 Identity Server is shipped with default PIP attribute finder which has been connected with its own user store (embedded LDAP server). Therefore to retrieve attributes of above created users (groups, emails and etc), We do not want to write new PIP and we can just use default PIP module.
Sample Web Application
Sample project for Medi Com web application, can be found from here. You can easily deploy Web Application using Tomcat or else WSO2 Application Server. Here i tried out it with Tomcat 7. Please do necessary changes in web.xml according to your setup.
following are the configuration that is needed be changed in web.xml
- backEndServerUrl – Web Service url of patient data web service which is “http://localhost:9765/services/MediComPatientService”
- pdpServerHostName – authorization server host name (WSO2 Identity Server host name i.e localhost)
- pdpServerPort – authorization server SSL port (WSO2 Identity Server SSL port i.e 9443)
- pdpServerUserName – authorization server user name (WSO2 Identity Server default user name i.e admin)
- pdpServerPassword – authorization server user password (WSO2 Identity Server default user password i.e admin)
- trustStoreFile – authorization server’s certificate is contains trust store file (By default you can point to the client-truststore.jks file which can be found at <IS_HOME>/repository/resources/security directory)
- trustStorePassword – trust store password (Password of client-truststore.jks file is “wso2carbon”)
- engagePEPHandler – whether to mention, PEP handler must engage not… (We can know about this property later)
Then Web application contains following dependencies.
- PEP module to call the web service API of the WSO2 Identity Server PDP. This uses the sample PEP agent which can be found at here
- Service stub module of the Medi Com web service
Any one can go through Web application source code and modify it as you want.
Sample Message interceptor
Here we need to intercept the message going from Web Application to Web Service. In real use cases, we can use a ESB (such as WSO2 ESB) for this. To demostrator this, I would like to use axis2 handler. As we are using axis2 client to send the message from Web application. We can engage axis2 handler in to message sending and receiving path of the axis2 client.
Please find sample axis2 handler from here. In this handler, SOAP message is extracted and Body part of the SOAP message is send to PDP for authorization with user name and the action (that are received via transport headers). This is a simple code, and you can understand what is going on there by looking at the code. This axis2 handler also using the sample PEP agent which can be found at here to call PDP APIs
Step 1 Copy axis2 module (.mar file) in to the <TOMCAT>/webapps/MediCom/WEB-INF/lib/
Step 2 Enable handler by setting following parameter in the web.xml file which can be found at <TOMCAT>/webapps/MediCom/WEB-INF
<init-param>
<description>engagePEPHandler</description>
<param-name>engagePEPHandler</param-name>
<param-value>true</param-value>
</init-param>
Defining XACML Policies
Now we are done with the setup. Lets define a XACML policy according to the requirement. Following are the expected access rules for phase 1.
Policy 1. Lets define a policy to control the static UI items (home.jsp page) that are shown in the Web Application. As following
- Patients can only read patient data and They can only see the UI option for that.
- Physician can only read and update patient data and They can only see the UI option for that.
- Administrator can only create and delete patient data and They can only see the UI option for that.
You can easily define this policy using Identity Server’s XACML editor. As following. You can find more details about simple policy editor from here
XACML Policy can be found at here.
Policy 2 Lets define a policy to control access for read operation in the web service. Here we are using XPath base policies to extract data from SOAP Body and to do the evaluation
- Patients can read their own data only and they can not read any other patient data.
- Physicians can read only the data that is related to his/her own patient.
XACML Policy can be found here.
Please upload these policies in to WSO2 Identity Server’s PDP. Please find more details on uploading existing policies from here
Important Note : Due to XPath issue in Identity Server 4.5.0. It would not provide correct result for Policy 2 . Therefore Please apply following patched jar that is attached in public jira
Now you can play with your web application…. Keep your setup up and running….. Lets enforce more policies later for this scenario.