Showing posts with label XACML. Show all posts
Showing posts with label XACML. Show all posts

Tuesday, October 9, 2012

Securing an exisiting WebApp using Entitlement Servlet Filter

Entitlement Servlet Filter is for check the Authorization of the requests which are coming to a webapp. This guide will tel you how to add that to a existing web of yours. You can read more about Entitlement Servlet Filter Here.

The steps to add Entitlement Servlet Filter to your Web App :

  • Add one of J2EE Authentication Mechanism to the WebApp. (Still Entitlement Filter Support Basic Auth Only). To do this task add following to the web.xml of your WebApp.
     <security-constraint>
        <display-name>Example Security Constraint</display-name>
        <web-resource-collection>
            <web-resource-name>Protected Area</web-resource-name>
        <!-- Protected URL -->
            <url-pattern>/protected.jsp</url-pattern>
            <!-- If you list http methods, only those methods are protected -->
            <http-method>DELETE</http-method>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>PUT</http-method>
        </web-resource-collection>
        <auth-constraint>
            <!-- Anyone with one of the listed roles may access this area -->
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- Default login configuration uses form-based authentication -->
    <login-config>
        <auth-method>BASIC</auth-method>
        <!--<auth-method>FORM</auth-method>-->
        <realm-name>Example Form-Based Authentication Area</realm-name>
        <form-login-config>
            <form-login-page>/protected.jsp</form-login-page>
        </form-login-config>
    </login-config>

    <!-- Security roles referenced by this web application -->
    <security-role>
        <role-name>everyone</role-name>
    </security-role>
    <security-role>
        <role-name>admin</role-name>
    </security-role>

  • Engage the Entitlement Servlet Filter. To do this task add following to the web.xml of your WebApp.
    <!-- Filter mappings used to configure URLs that need to be authorized  -->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/protected.jsp</url-pattern>
    </filter-mapping> 

  • Provide necessary parameters to the Entitlement Servlet filter. To do this task add following to the web.xml of your WebApp.
    <!-- The scope in which the subject would be available.  Legal values are basicAuth, request-param, request-attribute, session -->
    <context-param>
        <param-name>subjectScope</param-name>
        <param-value>basicAuth</param-value>
    </context-param>

    <!-- The name of the identifier by which to identify the subject -->
    <context-param>
        <param-name>subjectAttributeName</param-name>
        <param-value>username</param-value>
    </context-param>

    <!-- The username to perform EntitlementService query-->
    <context-param>
        <param-name>userName</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The password to perform EntitlementService query -->
    <context-param>
        <param-name>password</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The URL to perform EntitlementService query-->
    <context-param>
        <param-name>remoteServiceUrl</param-name>
        <param-value>https://localhost:9443/services/</param-value>
    </context-param>
    
    <!-- EntitlementFilter Settings -->
    <filter>
        <filter-name>EntitlementFilter</filter-name>
        <filter-class>org.wso2.carbon.identity.entitlement.filter.EntitlementFilter</filter-class>

        <!--Client Class that extends AbstractEntitlementServiceClient. Legal values are basicAuth, soap and thrift.
        Default is 'thrift'.-->
        <init-param>
            <param-name>client</param-name>
            <param-value>basicAuth</param-value>
        </init-param>

        <!--Decision caching at PEPProxy. Legal values are simple and carbon.-->
        <init-param>
            <param-name>cacheType</param-name>
            <param-value>simple</param-value>
        </init-param>

        <!--Maximum number of cached entries. Legal values are between 0 and 10000 -->
        <init-param>
            <param-name>maxCacheEntries</param-name>
            <param-value>1000</param-value>
        </init-param>

        <!-- Time interval for which cached entry is valid.-->
        <init-param>
            <param-name>invalidationInterval</param-name>
            <param-value>100000</param-value>
        </init-param>

        <!-- URL ro redirect to if authorization fails -->
        <init-param>
            <param-name>authRedirectUrl</param-name>
            <param-value>/index.jsp</param-value>
        </init-param>

    <!-- This will be used if the transport type is thrift. -->
        <init-param>
            <param-name>thriftHost</param-name>
            <param-value>localhost</param-value>
        </init-param>

        <!-- This will be used if the transport type is thrift.-->
        <init-param>
            <param-name>thriftPort</param-name>
            <param-value>10500</param-value>
        </init-param>

    </filter> 


So after following these steps your webApp is successfully secured with Entitlement Filter. You can find a sample project here.
Also make sure that you have to put the org.wso2.carbon.identity.entitlement.filter_4.0.2.jar, org.wso2.carbon.identity.entitlement.proxy_4.0.2  and org.wso2.carbon.identity.entitlement.stub_4.0.0.jar to your java classpath. The links for those jar is here. Also you can build those jars by using these links.

https://svn.wso2.org/repos/wso2/carbon/platform/trunk/service-stubs/org.wso2.carbon.identity.entitlement.stub/
https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.proxy/
https://svn.wso2.org/repos/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.filter/

Thursday, September 6, 2012

XACML Policy Enforcement Point(PEP) Proxy for WSO2 Identity Server

As you all know The WSO2 Identity Server provides  entitlement management  by XACML fine-grained policy based access control. In  this post I will introduce a Proxy Components for use this functionality in JAVA applications. This will make the users life easy in following ways,
  • User have to invoke a method in the proxy to get a entitlement decision.
  • User don't have to implement XACML request related things to use a XACML policy hosted in IS. The proxy hides those complexity from user.
  • Entitlement requests can be sent either using XACML 3.0 or  XACML 2.0.
  • The proxy provides list of methods which will most of the authorization request scenarios which a user can have.
  • User can use SOAP, Thrift or JSON to PDP PEP communication. User doesn't have to worry about the communication implementation.
  • Several PEPs can use same Proxy to communicate with several PDPs(WSO2 IS instances) at the same time.
Following diagram will show the functionality of the PEP Proxy,


Here XACML PEP can be any JAVA application. I have given a example application in my previous blog posts, http://www.insightforfuture.blogspot.com/2012/07/providing-xacml-fine-grained.html and http://www.insightforfuture.blogspot.com/2012/07/providing-xacml-fine-grained_22.html. In that I have described a Servlet Filter which uses this PEP proxy for give authorization to webapps.

The following list will show the API methods given in PEP Proxy,
  • String getDecision(Attribute[] attributes)
  • String getDecision(Attribute[] attributes, String appId) 
  • String getDecision(String subject, String resource, String action, String environment)
  • String getDecision(String subject, String resource, String action, String environment, String appId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, String domainId) 
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, String domainId, String appId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, Attribute[] attributes, String domainId)
  • boolean subjectCanActOnResource(String subjectType, String alias, String actionId,
                                               String resourceId, Attribute[] attributes, String domainId, String appId)
  • List<String> getActionableChidResourcesForAlias(String alias, String parentResource,
                                                               String action)
  • List<String> getActionableChidResourcesForAlias(String alias, String parentResource,
                                                               String action, String appId) 
  • List<String> getResourcesForAlias(String alias)
  • List<String> getResourcesForAlias(String alias, String appId)
  • List<String> getActionableResourcesForAlias(String alias)
  • List<String> getActionableResourcesForAlias(String alias, String appId)
  • List<String> getActionsForResource(String alias, String resources)
  • List<String> getActionsForResource(String alias, String resources, String appId)
Here you can see that there are duplicates of same method with "String appId" and without. When the proxy is initialized it will assign a default primary PEP as defaultAppId. That means the PDP mapping for the defaultAppId is used for make the queries. When  we specify a specific PEP configuration by giving "String appId", PEP Proxy will use those configuration to make the quires from WSO2 IS. All the methods which doesn't have "String appId" argument will use the default configuration.

Following JAVA class will give a example to use PEP Proxy. I used a Sample XACML policy hosted in WSO IS. That policy is given below Also,

JAVA Class :

package org.wso2.carbon.identity.entitlement.proxy;

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

public class Test {


    public static void main(String arg[]) throws Exception {

        PEPProxy pepProxy;
        //Initializing the PEP Proxy

        System.setProperty("javax.net.ssl.trustStore", "wso2carbon.jks");
        System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");

        Map<String,Map<String,String>> appToPDPClientConfigMap = new HashMap<String, Map<String,String>>();

        //Configuration to Initialize SOAP Client
        Map<String,String> clientConfigMapSOAP = new HashMap<String, String>();
        clientConfigMapSOAP.put("client", "soap");
        clientConfigMapSOAP.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapSOAP.put("userName", "admin");
        clientConfigMapSOAP.put("password", "admin");
        clientConfigMapSOAP.put("reuseSession", "false");

        appToPDPClientConfigMap.put("SOAP_APP", clientConfigMapSOAP);

        //Configuration to Initialize Basic Authentication Client
        Map<String,String> clientConfigMapBasicAuth = new HashMap<String, String>();
        clientConfigMapBasicAuth.put("client", "basicAuth");
        clientConfigMapBasicAuth.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapBasicAuth.put("userName", "admin");
        clientConfigMapBasicAuth.put("password", "admin");

        appToPDPClientConfigMap.put("BasicAuth_APP", clientConfigMapBasicAuth);

        //Configuration to Initialize Thrift Client
        Map<String,String> clientConfigMapThrift = new HashMap<String, String>();
        clientConfigMapThrift.put("client", "soap");
        clientConfigMapThrift.put("serverUrl", "https://localhost:9443/services");
        clientConfigMapThrift.put("userName", "admin");
        clientConfigMapThrift.put("password", "admin");
        clientConfigMapThrift.put("reuseSession", "false");
        clientConfigMapThrift.put("thriftHost", "localhost");
        clientConfigMapThrift.put("thriftPort", "10500");

        appToPDPClientConfigMap.put("Thrift_App", clientConfigMapThrift);


        PEPProxyConfig config = new PEPProxyConfig(appToPDPClientConfigMap,"SOAP_APP", "Simple", 10000, 100);
        pepProxy = new PEPProxy(config);

        String result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "");
        System.out.println(result);
        result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "", "BasicAuth_APP");
        System.out.println(result);
        result = pepProxy.getDecision("admin", "/Entitlement_Sample_WebApp/protected.jsp", "GET", "", "Thrift_App");
        System.out.println(result);
        boolean bResult = pepProxy.subjectCanActOnResource("urn:oasis:names:tc:xacml:1.0:subject:subject-id", "admin", "GET", "/Entitlement_Sample_WebApp/protected.jsp", "");
        System.out.println(bResult);
    }
}
Samples XACML Policy :

<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"  PolicyId="Entitlement_Filter_Sample_Policy" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable" Version="1.0">
    <Target></Target>
    <Rule Effect="Permit" RuleId="Rule1">
        <Target>
            <AnyOf>
                <AllOf>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">/Entitlement_Sample_WebApp/protected.jsp</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"></AttributeDesignator>
                    </Match>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">GET</AttributeValue>
                        <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"></AttributeDesignator>
                    </Match>
                    <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">
                        <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">admin</AttributeValue>
                        <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"></AttributeDesignator>
                    </Match>
                </AllOf>
            </AnyOf>
        </Target>
    </Rule>
</Policy>         

To test the PEP Proxy, You can do following steps,
  • Run a WSO2 IS Server 
  • Host the given sample policy
  • Run this Java Class with the dependency jar of PEPProxy. You can get that by building the source given below. That will give you the latest jar of PEPProxy. What you have to do is run mvn clean install in the source folder.
You can find the source of the PEP proxy in http://wso2.org/svn/browse/wso2/carbon/platform/trunk/components/identity/org.wso2.carbon.identity.entitlement.proxy/.I think this post helps you a lot to use IS inf future works.Also contact me if you have any problem. this was a Internship project of me at WSO2.  Please read following to have better understanding about WSO2 IS and related stuff.

 

Sunday, July 22, 2012

Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 2

I have discussed about XACML Fine Grained Authorization and how we can use WSO2 IS as a XACML engine in the previous post, Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 1 .

So as we know we can use WSO2 Application Server or Apache Tomcat or any other web container to host our web apps. So if there is a requirement to provide authorization to those web apps? That means some one want to allow access to there web apps on a fine grained manner. This has been done in the WSO2 platform. That was a project of mine. So using WSO2 Identity server as the XACML Policy Decision Point (PDP) we can provide fine grained authorization to webapps. This PDP can be access via a web service called Entitlement Service.

So what will the Policy Enforcement Point(PEP) for the webapp authorization ? After having some discussions we thought that a Servlet Filter will be the ideal solution. Any webapp developer can define a servlet filter which they want to use. Also we can use servlet filter in any kind of webapp container.

On that decision we have created a servlet filter which user can use to provide authorization to their web apps. We gave the name Entitlement Servlet Filter to that. It uses a Proxy to communicate with WSO2 Identity Server. The Entitlement PEP Proxy is responsible for following tasks,
  • There is a service in the WSO2 IS called Entitlement Service, that service is used to evaluate XCAML requests.
  • That is a admin service which can be used by the Admin Role.
  • To use that service we have to log in to the IS using AuthenticationAdmin Service.
  • So PEP Proxy log in to the IS as admin, so we can use it's Entitlement Service to evaluate requests coming.
  • We provide following parameters to PEP Proxy to evaluate the request against XACML policies in the WSO2 IS, UserName, ResourceName, Action and Environment. So it queries IS using the provided parameters and gives us the authorization decision.
The following digram shows how the the servlet filter gets the authorization decision,


The next problem is how we should obtain the parameters, UserName, ResourceName, Action and Environment. Exept the user name others we have. Because they are all related tot the web app. How we can get the user name? For that we used J2EE authentication mechanisms,
  • Basic Authentication
  • Client Cert Authentication
  • Digest Authentication
  • Form Authentication
After the authentication we can obtain the username in the the servlet filter. So all the parameters are found now.
As shown in the digram, when a request comes to a particular weapp which has the engaged Entitlement Servlet Filter it obtains the parameters UserName, ResourceName, Action and Environment. Then it initialize the PEP Proxy to communicate with WSO2 IS. After that it send the parameters and get the Entitlement decision. On the provided decision it stop or pass the request which has came to the web app. 

The next critical thing is how the user can engage the Entitlement Servlet Filter. For that we  use the web.xml. The following shows a example web.xml which configures the Entitlement Servlet Filter.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">

    <!-- Sample deployment descriptor configuration for EntitlementFilter -->

    <!-- The scope in which the subject would be available.  Legal values are basicAuth,request-param, request-attribute, session -->
    <context-param>
        <param-name>subjectScope</param-name>
        <param-value>request-param</param-value>
    </context-param>

    <!-- The name of the identifier by which to identify the subject -->
    <context-param>
        <param-name>subjectAttributeName</param-name>
        <param-name>userName</param-name>
    </context-param>

    <!-- The username to perform EntitlementService query-->
    <context-param>
        <param-name>userName</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The password to perform EntitlementService query -->
    <context-param>
        <param-name>password</param-name>
        <param-value>admin</param-value>
    </context-param>

    <!-- The URL to perform EntitlementService query-->
    <context-param>
        <param-name>remoteServiceUrl</param-name>
        <param-value>https://localhost:9443/services</param-value>
    </context-param>

    <!-- EntitlementFilter Settings -->
    <filter>
        <filter-name>EntitlementFilter</filter-name>
        <filter-class>org.wso2.carbon.identity.entitlement.filter.EntitlementFilter</filter-class>

        <!--
  Client class that extends AbstractEntitlementServiceClient. Legal values are basicAuth, soap and thrift.
  Default is 'thrift'.
        -->
        <init-param>
            <param-name>client</param-name>
            <param-value>basicAuth</param-value>
        </init-param>

        <!--
         Decision caching at PEPProxy. Legal values are simple and carbon.This parameter is optional.
         If not specified no caching is done.
        -->
        <init-param>
            <param-name>cacheType</param-name>
            <param-value>simple</param-value>
        </init-param>

        <!--
         Maximum number of cached entries. Legal values are between 0 and 10000 .
         Only works with caching.
        -->
        <init-param>
            <param-name>maxCacheEntries</param-name>
            <param-value>1000</param-value>
        </init-param>

        <!-- Time interval for which cached entry is valid. Only works with simple cache type. -->
        <init-param>
            <param-name>invalidationInterval</param-name>
            <param-value>100000</param-value>
        </init-param>

        <!-- URL ro redirect to if authorization fails -->
        <init-param>
            <param-name>authRedirectUrl</param-name>
            <param-value>/index.jsp</param-value>
        </init-param>

        <!-- Thrift host to be used if using 'thrift' client -->
        <init-param>
            <param-name>thriftHost</param-name>
            <param-value>localhost</param-value>
        </init-param>

        <!-- Thrift port to be used if using 'thrift' client -->
        <init-param>
            <param-name>thriftPort</param-name>
            <param-value>10500</param-value>
        </init-param>
    </filter>

    <!-- Filter mappings used to configure URLs that need to be authorized  -->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/protected.jsp</url-pattern>
    </filter-mapping>

    <!-- Mandatory mapping that needs to be present to work with PEP cache update authorization-->
    <filter-mapping>
        <filter-name>EntitlementFilter</filter-name>
        <url-pattern>/updateCacheAuth.do</url-pattern>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <!-- EntitlementCacheUpdateServlet settings-->
    <servlet>
        <servlet-name>EntitlementCacheUpdateServlet</servlet-name>
        <servlet-class>org.wso2.carbon.identity.entitlement.filter.EntitlementCacheUpdateServlet
        </servlet-class>

        <!-- HTTPS port of the web container used when redirecting request to come over https port for cache update authentication -->
        <init-param>
            <param-name>httpsPort</param-name>
            <param-value>9453</param-value>
        </init-param>

        <!-- Authentication mode for cache update. Legal values are webapp and wso2is -->
        <init-param>
            <param-name>authentication</param-name>
            <param-value>webapp</param-value>
        </init-param>

        <!-- Authentication page used for cache update authentication. Legal values are default and custom -->
        <init-param>
            <param-name>authenticationPage</param-name>
            <param-value>default</param-value>
        </init-param>

        <!-- Authentication page URL used for cache update authentication. Works only with custom for authenticationPage -->
        <init-param>
            <param-name>authenticationPageUrl</param-name>
            <param-value>/updateCache.html</param-value>
        </init-param>
    </servlet>

    <!-- Servlet mapping needed for cache update authentication -->
    <servlet-mapping>
        <servlet-name>EntitlementCacheUpdateServlet</servlet-name>
        <url-pattern>/updateCache.do</url-pattern>
    </servlet-mapping>
</web-app>

Providing XACML Fine Grained Authorization to WebApps : Using WSO2 Identity Server - Part 1

What is XACML Fine Grained Authorization ?

When we talk about a resource ( Here resource is the Webapp hosted in either WSO2 Application Server, Apache Tomcat  etc.) we have to talk about authorization of the users who use those resources. That means some users are authorized to uses the resource and some are not. So what is mean by Fine Grained Authorization ? Traditionally authorization of the user for resource is decided by the users,resource and the action which user does on the resource. But  if we can provided authorization based on user, resource, action user does on resources, environment, time, user's role etc. that is fine grained authorization. We use more details of the scenario to decide the authorization of the user. For a example if there is requirement like this, " This document can be edited by only AndunSLG, who is a Teacher and between 8am to 10am at the school office premises". The given requirement is a fine grained authorization requirement.
To evaluate such requirement against users request, we have to document those fine grained authorization requirements. Those are called Polices. XACML is used to document these kind of polices. We can evaluate user's requirements against these XACML polices using a XACML engine.
We can use WSO2 Identity Server for this requirement. It have a XACML Policy Engine where users can evaluate there requests. Also it provides so many functionalities related to XACML Authorization At the end I have given lot of references where you can learn about XACML.

References,

XACML Policy Language
WSO2 Identity Server