Sunday, December 18, 2011

"Entitlement Service" - XACML PDP as a web service

Being part of WSO2 middleware platform, XACML PDP (Policy Decision Point) functionality in Identity Server is exposed as a web service called 'Entitlement Service' whose implementation can be found here.

Describing XACML reference architecture and XACML policy language is out of the scope of this post and you can refer to my previous post to get an overall idea about an example solution based on XACML.

A PEP (Policy Enforcement Point) can consume the EntitlementService through a SOAP based client and invoke its "getDecision" method to obtain the authorization decision for a given XACML authorization request. Such a PEP exists in WSO2 ESB as a mediator called EntitlementMediator.

In this post, I will take you through a simple java client which acts as a PEP.

1) First of all, lets look at the communication flow between a PEP and PDP of IS with SOAP based implementation:

In the above diagram, in addition to the Entitlement Service, there is also AuthenticationAdmin service comes into play in between client and the EntitlementService.

What does it do?
It authenticates the clients against the user store before the client is capable of invoking an AdminService. Any request coming to the back end server is hit by the Authentication Handler (which is an axis2 handler) and if that request is for an AdminService, handler checks whether the request is authenticated.

Now comes the question, what is an AdminService?
Well.. In WSO2 Carbon, we have a concept called AdminService whose charaterisitcs are as follows:
  • Can only be invoked by an authenticated user in the system.
  • Exposed over secure transport.
Entitlement Service is exposed as an AdminService since it exposes the functionality of obtaining authorization decision and since it communicates security sensitive information.

You can read more about carbon authentication framework from here.

2) Before looking at the PEP client code, lets setup the PDP of IS with a sample XACML policy.

Start the identity server->login to management console->access Entitlement -> Administration -> Add New Entitlement Policy

WSO2 Identity Server has a rich XACML UI editor through which you can configure XACML policies easily.

Our XACML policy will enforce following rule: Read access to the resource called 'ABCResource' is only allowed to users belonged to admin role and all the other request to this rersource will be denied.

Please follow the following screen shots to compose the policy through UI editor (If the images are not clear, please click on them to view the enlarged version).

i). Here we define policy name, rule combining algorithm and the policy target.

ii). Next we define the two rules with 'Permit' effect for admin users and 'Deny' effect for all other requests.



iii) We can evaluate the XACML policy by sending a mock XACML request from the 'TryIt' tool provided by the Identity Server as shown below.


In the above request, a user in role 'eng' is trying to read the resource 'ABCResource' which should result in deny effect when evalated against the defined XACML policy.

iv). You can also obtain the exact XACML request created by the above 'TryIt' tool by selecting "Create Request" which you can observe as below.


3) Java client as PEP
You can download the source code of the SOAP based client which can act as a PEP and consume Entitlement Service - PDP of IS, to obtain the authorization decisions.
(Here I have only illustrated how to consume PDP, you can continue implementing a complete PEP who tracks access requests from users, composes XACML requests for those resource access requests, gets them authorized by PDP and responds to users accordingly.)

Lets go through the important code segments of the client code.
(Please note that I have trimmed off some of the code segments for the sake of brevity. Please use full source code in the above link.)
public class EntitlementClient {

    private static String serverUrl = "https://localhost:9443/services/";
    //some code goes here

    //sample XACML request captured from TryIt tool of IdentityServer. 
    private static String sampleRequest = "
                                            //actual request is removed for brevity
                                          ";

    public static void main(String[] args) {

        try {

            //set trust store properties required in SSL communication.
            System.setProperty("javax.net.ssl.trustStore",
                               "/home/hasini/WSO2/wso2is-3.2.0/repository/resources/security/wso2carbon.jks");
            System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
            
            //initialize authentication admin stub
            EntitlementClient remoteEntitlementClient = new EntitlementClient();

            //login using authentication admin stub providing valid credentials
            remoteEntitlementClient.login("admin", "admin");

            //initialize entitlement service stub with obtained auth cookie
            remoteEntitlementClient.initEntitlementClient();

            //invoke EntitlementService by passing the XACML request and obtain the authorization decision
            String decision = entitlementServiceClient.getDecision(sampleRequest);
            //print the authorization decision
            System.out.println(decision);

line07: hard coded XACML request which will be given as input when invoking Entitlement Service. This can be obtained from TryIt tool as described in section 2.iv

line16,18: Being AdminServices, AuthenticationAdmin and Entitlement Service are exposed over HTTPS. So here we need to set SSL system properties. Please change them to suit your environment.

line21-30: You can understand by relating the comments in the code with the communication flow illustrated in secion 1.

Setting up and running the client:
In order to run the client, please make sure you have included the two paths: "[IS_home]/lib/api" and "[IS_home]/repository/components/plugins" into your classpath.

So what?
I hope you got an idea about how PDP in IS is exposed and how to write a custom PEP to consume it and about the communication flow between the two.
In fact this is written to build up the foundation for another post I am going to write in the near future. Stay tuned.. and Have a nice day..!!

Saturday, December 10, 2011

Installing a new keystore into WSO2 Carbon based products.

Applies to: WSO2 Carbon 3.2.0 based products.

WSO2 carbon products are shipped with a default keystore named wso2carbon.jks which resides in [CARBON_HOME]/repository/resources/security directory. This is the keystore with private/public key pair which is used for encrypting sensitive information, encryption/signature purposes in WS-Security and also for communication over SSL.

It is recommended to replace this with a keystore with self signed or CA signed certificates when the products are deployed in production environments. Because wso2carbon.jks is available with open source WSO2 products and anyone can have access to the private key of the default keystore.

Following is a step by step guide to achieve the $subject.

1). Create a new keystore with a private and public key pair using keytool utility that ships with JDK installation.

Make sure you have installed Java and set your PATH env variable to [i.e : JAVA_HOME\bin]
Go to [CARBON_HOME]/repository/resources/security directory and execute the following command:
keytool -genkey -alias mycert -keyalg RSA -keysize 1024 -keypass mypkpassword -keystore mykeystore.jks -storepass mypkpassword

Note: With tomcat SSL configuration, we need to have both keystore password and private key password the same.

You will be prompted to provide necessary information to construct the DN of the certificate.
Once you provide the information, a keystore file will be generated inside the same directory above, with:
keystore name=mykeystore.jks
alias of the public certificate=mycert
private key password & keystore password=mypkpassword

You can view the contents of the generated keystore from the following command:
keytool -list -v -keystore mykeystore.jks -storepass mypkpassword

2). Get the public certificate signed: You can either get your public certificate signed by a CA(recommended for production environment) or continue using the above generated self signed certificate (for local testing purposes).

Please refer to: http://blog.facilelogin.com/2008/03/keystore-management-part-i.html
for a step by step guide on how to get your public certificate signed by a CA and importing CA certs into your keystore. Here, in this guide I will continue to use the self signed certificate.

3). Export your public certificate from the keystore and import it into the trust store.

In SSL handshake, client side needs to verify the certificate presented by the server side. For that, client usually stores the certificates it trusts, in a trust store.
Related to SSL communication of WSO2 Carbon products, this trust store is set as client-truststore.jks which resides in the same above directory as the keystore.
Therefore we need to import the new public certificate into this trust store for Front End and Back End communication of WSO2 products to be properly happened over SSL.

Export the new public certificate with following command:
keytool -export -alias mycert -keystore mykeystore.jks -storepass mypkpassword -file mycert.pem
Above will export the public certificate into a file called mycert.pem in the same directory.

Now import it into client-truststore.jks with following command:
keytool -import -alias mynewcert -file mycert.pem -keystore client-truststore.jks -storepass wso2carbon
(Password of client-truststore.jks keystore is: wso2carbon)

4). Change the configuration files:

You need to locate and change the entries in the below elements of following configuration files which resides in [carbon_home]/repository/conf to point to the new keystore as highlighted below:

i. carbon.xml (Here we specify the keystore which is used by default for encrypting sensitive information to be stored and also for encryption/signature purposes in WS-Security)
 
${carbon.home}/repository/resources/security/mykeystore.jks 
JKS 
mypkpassword 
mycert 
mypkpassword 


ii. mgt-transports.xml (Here we specify the keystore which contains the public certificate to be fetched when accessing Management Console over SSL for all the WSO2 products and it is the same keystore which contains the certificate used when accessing services exposed over HTTPS as well, except for WSO2 ESB.)
 
${carbon.home}/repository/resources/security/mykeystore.jks 
 
mypkpassword

iii. axis2.xml (Only for WSO2 ESB) (WSO2 ESB uses different HTTPS transport sender and receiver for accessing the services exposed over HTTPS as below, and the keystore used for this purpose is specified in the following configuration)
 
8243 
true 
org.wso2.carbon.transport.nhttp.api.NHttpGetProcessor 
 
 
repository/resources/security/mykeystore.jks 
JKS 
mypkpassword 
mypkpassword 
 
 
 
 
repository/resources/security/client-truststore.jks 
JKS 
wso2carbon 
 
 


 
true 
 
 
repository/resources/security/mykeystore.jks 
JKS 
mypkpassword 
mypkpassword 
 
 
 
 
repository/resources/security/client-truststore.jks 
JKS 
wso2carbon