2013/11/25
25 Nov, 2013

Enabling Fine-Grained XACML Authorization with PIP points Using WSO2 Identity Server

  • Umesha Gunasinghe
  • Solutions Engineer - WSO2

Introduction

WSO2 Identity Server supports policy-based access control with XACML 2.0 and 3.0. The XACML engine of the identity server acts as a PAP, PDP and a PIP. The entitlement service of the identity server can be enforced via a PEP.

PAP - Policy Administration Point

PDP - Policy Decision Point

PIP - Policy Information Point

PEP - Policy Enforcement Point

In certain situations, the PDP (request and policy) might not have the required details in order to authorize a particular user to access a resource. In this scenario, a PIP can be registered in WSO2 IS to get the needed information from outside resources, and provide the authorization decision with PDP.

Table of contents

1. Sample Scenario

2. Architecture of the solution

3. Setting up the solution

  • 3.1 Writing and deploying the JAX-RS service

  • 3.2 Writing and registering the PIP point with WSO2 IS

  • 3.3 Writing the XACML policy and checking with TryIt tool

  • 3.4 Executing the authorization scenario using SoapUI

4. Sample Setup

5. Summary

6. References

1. Sample scenario

A particular user is trying to access a resource by providing his user ID. The policies are written to verify the username and to grant access. Therefore, the PDP needs more information in order to take a decision on the authorization. A PIP is registered with IS to call an outside resource to get user information, in this case the username. With the relevant information, PDP can give out the authorization decision to give access permission to the user.

Example scenario steps

1) User ‘John’ is trying to get READ access with his user ID.

2) Authorization should be given by validating the user ID against the username, requesting username information via a PIP point.

3) PIP is requesting information from a web service.

2. Architecture of the solution

Architecture of the Solution Image

According to the above diagram, the user request is sent using PEP (to execute this scenario we use SoapUI as the PEP. We can also configure to use WSO2 ESB as the PEP since it contains an entitlement mediator). The policy is written using the PAP of the Identity Server, and published to the PDP. When the request comes in, the entitlement engine gets the username from the web service (in this case JAX-RS service, which is deployed in WSO2 Application Server) user information via the PIP. Now let's look at how to set up this use case scenario step by step.

Used products

WSO2 Identity Server 4.5.0

WSO2 Application Server 5.1.0

3. Setting up the solution

3.1 Writing and deploying the JAX-RS Service

For this scenario, we have used a JAX-RS service.

Let's discuss the example service created for the scenario. You can create a simple User object class as follows by defining it as the root element.

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "User")

public class User {
	
	private String id;
    	private String name;
    	private String list;
    	private String group;

	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getList() {
		return list;
	}
	public void setList(String list) {
		this.list = list;
	}
	public String getGroup() {
		return group;
	}
	public void setGroup(String group) {
		this.group = group;
	}
}

Then you can write the JAX-RS service using the object created as User as follows:

When you are writing a JAX-RS service, the attention should be given to JAX-RS annotations. You can see that the @Path element is set for the service and two @GET methods are written each having the specific @Path defined.

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

@Path("/userservice/")
public class UserService {

	Map<String, User> users;

	public UserService() {
		users = new HashMap<String, User>();
		init();
	}

	final void init() {

		User u1 = new User();
		u1.setId("123");
		u1.setName("bob");
		u1.setList("List1, List 2, List 3");
		u1.setGroup("customer");

		User u2 = new User();
		u2.setId("124");
		u2.setName("john");
		u2.setList("List 2, Group 2, List 3");
		u2.setGroup("Banker");

		User u3 = new User();
		u3.setId("125");
		u3.setName("mary");
		u3.setList("List 3, Group 2, List 3");
		u3.setGroup("Manager");

		users.put(u1.getId(), u1);
		users.put(u2.getId(), u2);
		users.put(u3.getId(), u3);
	}

	@GET
	@Path("/users/{id}/")
	public User getUser(@PathParam("id") String id) {
		System.out.println("----invoking User, User id is: " + id);
		User u = users.get(id);
		System.out.println("Returning the user" + id + "details" + u.getName()
				+ u.getList());
		return u;
	}

	@GET
	@Path("/users/name/{id}")
	public String getUserName(@PathParam("id") String id) {
		System.out.println("----invoking User, User id is: " + id);
		User u = users.get(id);
		System.out.println("Returning the user" + id + "details" + u.getName());
		return u.getName();
	}

}

In this use case scenario we use the second service method created in which the @Path is set as "@Path("/users/name/{id}")".

Now we will look at how we can deploy the service using WSO2 Application Server and make sure this service is working by sending a request using Advanced Rest Client.

First of all you will have to download the Application Server from the WSO2 product page. Extract the product to a local folder and start the server. Once the server is started, go to the management console and type admin, admin to login as username and password, respectively. Then go to Manage>Applications>Add>JAX-WS/JAX-RS and upload the .war file of the JAX-RS service created (find the .war file of the service in the sample setup file that is attached to this article).

When the service is deployed you can see the service in the application list. When you click on the service you deployed in the list, you can get the following view where you can see the service details.

JAX-RS Service Deployed in Application Server Image

Get the service endpoint URL and give the service path in the Advanced Rest Client to send the requests as represented in the following image. Pay attention to the service URL.

Advanced Rest Client Request Image

3.2 Writing and registering the PIP point with WSO2 IS

As mentioned earlier WSO2 Identity server supports fine grained authorization with XACML 2.0/3.0 in IS 4.5.0. We can register PIP points to retrieve information related for authorization. For that, a PIP should be written and registered with IS. You can download a sample PIP from here. You can also find the sample PIP we have customized for this scenario in the attached setup samples file.

Followings are descriptions of main sections of our scenario code sample on how to customize to access the JAX-RS service deployed in the App Server.

1) This is the method that can be used to init the PIP module. Supported attributes should be added inside the init method. In our use case scenario, we are trying to find the username from calling the resource. Therefore, we can add the USERNAME attribute.

@Override
    public void init(Properties properties) throws Exception {
        // init this module and init supported attribute ids
        supportedAttributeIds.add("USERNAME");
    }

2) Then, the getAttributeValues method should be implemented to setup the connection to the service in the application server and get the required values.

@Override
    public Set<String> getAttributeValues(String subject, String resource, String action,
                                  String environment, String attributeId, String issuer) throws Exception {

        //setting up the connection
        String serviceURL = "https://localhost:9763/SimpleJaxRSService_1.0.0/services/user_service/userservice/users/name";

        // Sent HTTP GET request to query customer info
        System.out.println("Sent HTTP GET request to query user group information");

        //Sending the information via service url
        URL url = new URL(serviceURL + "/" + subject);
        InputStream in = url.openStream();
        System.out.println("printing the user details");
        String value = getStringFromInputStream(in);
        System.out.println(value);

        Set<String> lists = new HashSet<String>();

        lists.add(value);
        return lists;
    }

As you can see in the above code sample, the serviceURL is set to the username (which returns the username) and the subject(user ID) is passed to the method as user ID.

Now we need to register this PIP in WSO2 IS. Use the following steps to register the PIP point with IS.

1) First of all you have to build the PIP code and create the .jar file for the PIP. e.g. using maven

2) Then go to \wso2is-4.5.0\repository\components\lib and put that .jar file there

Important: You should remember to include other dependency .jar files you have downloaded to build the PIP code in the above location

3) Finally go to \wso2is-4.5.0\repository\conf\security and add the following line to the entitlement.properties file to register the PIP

PIP.AttributeDesignators.Designator.2=org.wso2.carbon.identity.samples.entitlement.pip.UserPIPAttributeFinder

UserPIPAttributeFinder is our sample PIP. Now you have your PIP registered with IS.

3.3 Writing the XACML policy and checking with Tryit tool

Now we need to look at how to write a simple XACML policy in WSO2 IS for our use case scenario. The JAX-RS service is written with user information. Let's say we have 'John' the user with user ID 124 and another user with user ID 125. Now we have a requirement to permit ‘John’ to read something. However, nobody else should be able to read it. We need to figure out how to handle this authorization scenario to allow ‘John’ to READ a particular resource. It is easy to write XACML policies with new user interface provided by WSO2 IS 4.5.0.

Download WSO2 Identity Server from the WSO2 product page

Then start and Login to Identity Server, and go to Home>Entitlement. There click on simple policy editor and you will be able to see the following screen.

Note: Since you have the Application Server running on localhost 9443 port, you have to set the offset of Identity Server to 1 for it to run on port 9444. This can be done by going into \wso2is-4.5.0\repository\conf and changing the offset tag of carbon.xml

Create XACML Policy Image

Now we need to fill in the necessary information.

1) First give the XACML policy a name

2) Then you can fill in a description

3) Then select what this policy is based on. For our scenario, this is based on the resource we have, which is the web service that is deployed in the Application Server. Therefore, we can select Resource

4) Then give the resource name

Note that the input values may change on what the policy is based on

5) Now let's focus on the bottom part. We do not intend to give child resource

Our user is 'John'

The action is READ

you can give an environment even.

Now we have filled the information we need to implement the policy. After filling the information regarding the XACML policy click on the finish button.

Now, we need think about the purpose of us registering the PIP. The reason for this is that we needed to get the required user information for authorization. What user information we were trying to access from the web service? It was the username that is given to the user ID. What have we actually done? We have written an XACML policy to give READ access to ‘John’.

Now, we need to mention in the policy "You have to give 'John' READ rights to certain information, but only the user ID of John is provided. Therefore, you have to verify the user ID with the username before granting any permission. You have to look for a PIP to get this information." But actually we haven't mention in the policy as to how to get this information.

Go to Home>Entitlement>PAP>Policy Administration>Policy

Open the policy you have created, and you can see the generated policy in an editable format.

XACML Policy Edit View Image

You can see the information we have given for the policy. Refer to the user information section. There you have to mention where to get the user information to enable access to ‘John’. For this you have to mention the attribute ID you have given when you wrote the PIP. In this case, it is 'USERNAME'. Now the policy knows how to find the USERNAME for ‘John’ since in our scenario the user gives information as user ID. Save the policy. Go to Policy Administration and Click on Publish to My PDP to publish the policy. Then go to Policy View and check whether the policy is Enabled; if it is disabled, Enable the policy.

Now we can try out the XACML policy we have written using WSO2 IS TryIt tool.

Go to PEP > TryItTool

TryIt Tool Image

Lets look at the picture above, and try understand the input values for the XACML request. Here, we are using the TryIt tool as the Policy Enforcement Point in the XACML engine. We are trying to send the request and enforce the policy to get the policy decision from PEP.

Let's fill out the input values as follows in the tool:

1) Resource - The service name you have given in the policy

2) Subject Name - This is the user who is trying to access. Here, we are sending the user ID of the user, where the policy sends the request to PIP to get the user information

3) Action - We mention the action of the user, in this case it is READ

4) Environment Name - since we haven't mentioned any in the policy, we do not have to input here

Now let's look at the Request created by the TryIt tool. Click on the Create Request button.

XACML Request Image

The request is created with the values we have filled out. Now let's Evaluate with PDP to get the decision. Click on Evaluate with the PDP button.

PDP Decision Image

You can see the decision is Permit. You can go back and try to evaluate with different input values and see the decision of the PDP. The policy only permits when user ID 124 is trying to READ.

3.4 Executing the authorization scenario using SoapUI

First we need to look at how to expose the entitlement service in the Identity Server.

1) Go to \wso2is-4.5.0\repository\conf and open the carbon.xml

2) Change to false as follows

Entitlement Service Attribute Image

3) Start the Identity Server

4) Copy and paste the following URL on the browser address bar

https://localhost:9444/services/EntitlementService?wsdl

If you have saved the settings correctly, you should be able to view the entitlement server wsdl

5) Save the wsdl file

Now let's see how you could use the wsdl and SoapUI to send requests.

1) Open SoapUI

2) Go to File in the top menu bar and select New SoapUI Project

3) Give a project and browse for the wsdl file

4) Then click OK and the simple requests for all operations will be created automatically

5) Then Select getDecisionByAttributes request

Select Request Image

6) Then fill in the parameter details as follows for our XACML policy we have written

Request Parameters Image

7) Then you have to authorize the request by entering authorization values as admin, admin for username and password, respectively

Now you can send the request and check for the decisions. The ‘Permit’ is received as the decision only when the user ID 124 is trying to READ.

4.Sample setup

Please find the sample codes and resource files attached at the end of the article. Refer to the ReadMe.txt file for details on the samples and how to set up the scenario with the provided sample files.

4.Summary

In this article, we have discussed how to enable fine-grained authorization with PIP points using WSO2 Identity Server. When a user authorization requests comes in, the XACML engine PDP can look for PIP points that are registered to retrieve the necessary information. These PIP points can be any resources that are outside of the system, and the PIP can call these for the retrieval of information. According to the information, the PDP can give out the authorization decision. We have used a JAX-RS service as our resource web service that gives us the user-related information, according to this scenario. We have deployed the service in the WSO2 Application server. Using the WSO2 IS PAP, we have written a policy to evaluate the XACML authorization request. The PIP point is registered with the identity server. The policy can be tried out with the identity server's TryIt tool. Once the scenario is set up, SoapUI is used to send the user requests.

5.References

1) WSO2 Identity Server - Managing Entitlement

2) Fine-Grained Authorization to RESTful Services with XACML

3) Deploying JAX-WS and JAX-RS Applications

 

About Author

  • Umesha Gunasinghe
  • Solutions Engineer
  • WSO2