Saturday, November 19, 2016

Authentication & Authorization Common Service Layer for WSO2 Carbon Platform

Here we are concerning about a common authentication & authorization layer in OSGi level. So in order to use it for REST APIs, we have introduce tomcat valves to intercept all the request that come to the wso2 product and use this service to authenticate and authorize the request.

Following digram explain the service details.



There are two OSGi services that provide the authentication and authorization service based on its own handlers. Anyone can write their own handlers for both and register in OSGi.
OOB, we have three authentication handlers,

1. OAuth2AccessTokenHandler
2. ClientCertificateBasedAuthenticationHandler
3. BasicAuthenticationHandler

Authorization handler based on our permission store against the user role. But anyone can write their own authorization handlers as well.

As an one of usage this services was to secure rest services in WSO2 IS itself. In order to do that, we have to intercept the request by using two valves,

org.wso2.carbon.identity.auth.valve.AuthenticationValve
org.wso2.carbon.identity.authz.valve.AuthorizationValve

So if you open the  catalina-server.xml , you can see the following content

<Engine name="Catalina" defaultHost="localhost">

            <!--Realm className="org.apache.catalina.realm.MemoryRealm" pathname="${carbon.home}/repository/conf/tomcat/tomcat-users.xml"/-->

            <Realm className="org.wso2.carbon.tomcat.ext.realms.CarbonTomcatRealm"/>

            <Host name="localhost" unpackWARs="true" deployOnStartup="false" autoDeploy="false"
                  appBase="${carbon.home}/repository/deployment/server/webapps/">

                <Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonContextCreatorValve"/>
                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="${carbon.home}/repository/logs"
                       prefix="http_access_" suffix=".log"
                       pattern="combined"/>
                <Valve className="org.wso2.carbon.tomcat.ext.valves.CarbonStuckThreadDetectionValve" threshold="600"/>
                <Valve className="org.wso2.carbon.tomcat.ext.valves.CompositeValve"/>

                <!-- Authentication and Authorization valve for the rest apis and we can configure context for this in identity.xml  -->
                <!--Valve className="org.wso2.carbon.identity.auth.valve.AuthenticationValve"/>
                <Valve className="org.wso2.carbon.identity.authz.valve.AuthorizationValve"/-->

            </Host>
        </Engine>

Here you can enable above valves to each service to intercept the request.

Then you have to specify which resource that you want to secure. To do that, you have to put the details as follows in identity.xml file.

<ResourceAccessControl>
        <Resource context="/api/identity/*" secured="true" http-method="all">
            <Permissions>/permission/admin/login</Permissions>
        </Resource>
    </ResourceAccessControl>



As in here, you can define which resource context(relative to the root context) must be secure under which http-methods. You can define either "all" or "post,get" like wise. And you can enable /disable the security on this context.

Then you can define which permission string should be under your role to authorize this resource by specifying Permission string in comma separated list.