Monday, November 30, 2015

Active Directory User Store Configurations for get LDAP users with their roles and role list WSO2 Servers

<?xml version="1.0" encoding="UTF-8"?>
<UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager">
  <Property name="ConnectionName">user_wso2ldap</Property>
  <Property name="ConnectionURL">ldap://youdomain.com:389</Property>
  <Property encrypted="true" name="ConnectionPassword">######</Property>
  <Property name="UserSearchBase">CN=Users,DC=rm,DC=gr,DC=testypf,DC=com</Property>
  <Property name="UserNameListFilter">(objectClass=organizationalPerson)</Property>
  <Property name="UserNameAttribute">sAMAccountName</Property>
  <Property name="UserNameSearchFilter">(&amp;(objectClass=organizationalPerson)(sAMAccountName=?))</Property>
  <Property name="ReadOnly">true</Property>
  <Property name="MaxUserNameListLength">100</Property>
  <Property name="MaxRoleNameListLength">100</Property>
  <Property name="UserRolesCacheEnabled">true</Property>
  <Property name="SCIMEnabled">false</Property>
  <Property name="DisplayNameAttribute">sAMAccountName</Property>
  <Property name="Disabled">false</Property>
  <Property name="ReadGroups">false</Property>
  <Property name="GroupSearchBase">ou=system</Property>
  <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
  <Property name="GroupNameSearchFilter">(&amp;(objectClass=groupOfNames)(cn=?))</Property>
  <Property name="GroupNameAttribute">cn</Property>
  <Property name="MembershipAttribute">member</Property>
  <Property name="MemberOfAttribute">memberOf</Property>
  <Property name="MultiAttributeSeparator">,</Property>
  <Property name="PasswordHashMethod">PLAIN_TEXT</Property>
  <Property name="ReplaceEscapeCharactersAtUserLogin">true</Property>
  <Property name="ConnectionPoolingEnabled">false</Property>
  <Property name="UserDNPattern"/>
  <Property name="DomainName">TEST</Property>
  <Property name="Description"/>
</UserStoreManager>
NOTE : Depend on the User store structure, CN, DC and etc values may changed.

Sunday, November 15, 2015

Get User Store Domain of login user when user store domain not provided WSO2 APIs

Sometimes when we accessing APIs, there are situations when authenticated user again WSO2 not provided user store domain. But it's essential to get the which user store the user has authenticated. It can be a user in Primary Store or Secondary User Stores. UserCoreUtil class has following method which will gives you the domain that user has authenticated.


if (!username.contains(CarbonConstants.DOMAIN_SEPARATOR)) {
    String userStoreDomain = UserCoreUtil.getDomainFromThreadLocal();
    if (!StringUtils.isEmpty(userStoreDomain)) {
        username = UserCoreUtil.getDomainFromThreadLocal() + CarbonConstants.DOMAIN_SEPARATOR + username;
    }
}

Wednesday, November 11, 2015

Configuring Mutual SSL in WSO ESB Proxy Services and REST APIs

Configuring Mutual SSL in WSO ESB Proxy Services and REST APIs

What Mutual SSL?

Mutual authentication is the process where client authenticate with server and vice versa. With this approach client clients can be make sure that they are dealing business exclusively with trusted entities and from the server's perspective it can be certain that all would-be users are attempting to gain access for legitimate purposes.Two-way SSL authentication is one way of achieving the mutual SSL. During mutual SSL negotiation process, application acting as an SSL client presents its certificate to the SSL server after the SSL server authenticates itself to the SSL client

Mutual SSL for proxy service

  1. Edit https transportListener in axis2.xml  in {ESB_HOME}/repository/conf/axis2/ folder and Add SSLVerifyClient to optional as follow.

<transportReceiver name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener">
  <parameter name="port" locked="false">8243</parameter>
  <parameter name="non-blocking" locked="false">true</parameter>
  <parameter name="httpGetProcessor" locked="false">org.wso2.carbon.transport.nhttp.api.PassThroughNHttpGetProcessor</parameter>
  <parameter name="keystore" locked="false">
     <KeyStore>
        <Location>repository/resources/security/wso2carbon.jks</Location>
        <Type>JKS</Type>
        <Password>wso2carbon</Password>
        <KeyPassword>wso2carbon</KeyPassword>
     </KeyStore>
  </parameter>
  <parameter name="truststore" locked="false">
     <TrustStore>
        <Location>repository/resources/security/client-truststore.jks</Location>
        <Type>JKS</Type>
        <Password>wso2carbon</Password>
     </TrustStore>
  </parameter>
  <parameter name="SSLVerifyClient">optional</parameter>
  <!--supports optional|require or defaults to none -->
</transportReceiver>
  1. Next step is to enable the mutual SSL per proxy as it’s not required to all the proxies. In order to do that, create a local entry in ESB with following policy

<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="MutualSSL">
  <wsp:ExactlyOne>
     <wsp:All>
        <sp:TransportBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
           <wsp:Policy>
              <sp:TransportToken>
                 <wsp:Policy>
                    <sp:HttpsToken RequireClientCertificate="true" />
                 </wsp:Policy>
              </sp:TransportToken>
              <sp:AlgorithmSuite>
                 <wsp:Policy>
                    <sp:Basic256 />
                 </wsp:Policy>
              </sp:AlgorithmSuite>
              <sp:Layout>
                 <wsp:Policy>
                    <sp:Lax />
                 </wsp:Policy>
              </sp:Layout>
           </wsp:Policy>
        </sp:TransportBinding>
        <rampart:RampartConfig xmlns:rampart="http://ws.apache.org/rampart/policy">
           <rampart:encryptionUser>useReqSigCert</rampart:encryptionUser>
           <rampart:timestampPrecisionInMilliseconds>true</rampart:timestampPrecisionInMilliseconds>
           <rampart:timestampTTL>300</rampart:timestampTTL>
           <rampart:timestampMaxSkew>300</rampart:timestampMaxSkew>
           <rampart:tokenStoreClass>org.wso2.carbon.security.util.SecurityTokenStore</rampart:tokenStoreClass>
           <rampart:nonceLifeTime>300</rampart:nonceLifeTime>
        </rampart:RampartConfig>
     </wsp:All>
  </wsp:ExactlyOne>
</wsp:Policy>

  1. Create a sample proxy service and configure the policy as follow.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="Test" transports="https" statistics="disable" trace="disable" startOnLoad="true">
  <target>
     <inSequence>
        <log level="full" />
        <respond />
     </inSequence>
  </target>
  <enableSec />
  <policy key="MutualSSLPolicy" />
  <description />
</proxy>
4. After that it required to create a new client keystore and truststore which need to configured  in the client that communicate with the ESB. Follow below steps to setup the configurations. (This uses keytool commands to configure the keystore, trustore and certificates

  1. Create client keystore name client-keystore.jks

 keytool -genkey -keyalg RSA -keystore  client-keystore.jks -alias wso2clientkeystore -dname     "CN=wso2clientkeystore" -validity 3650 -keysize
2048

  1. Export the keystore certificate which will need to be imported for the trustores

keytool -export -keyalg RSA -keystore client-keystore.jks -alias wso2clientkeystore  -file wso2clientkeystore.cert
  1. Next step is to create the client side truststore where it stores the client certificates (public keys)
keytool -import -file wso2clientkeystore.cert -alias wso2client -keystore wso2clienttrustore.jks
  1. Now it’s required to import the ESB Server public certificate to client side truststore. First export the public key of the keystore of ESB in {ESB_HOME}//repository/resources/security/wso2carbon.jks as follow

keytool -export -keyalg RSA -keystore /repository/resources/security/wso2carbon.jks -alias wso2carbon -file wso2carbon.cert


  1. Above certificate need to be imported to client side truststore which is wso2clienttrustore.jks

keytool -import -file wso2carbon.cert -alias wso2carbon -keystore wso2clienttrustore.jks
  1. Import the client side certificate to ESB client truststore located in  the {ESB_HOME}//repository/resources/security/client-truststore.jks

keytool -import -file wso2clientkeystore.cert -alias wso2clientkeystore -keystore /repository/resources/security/client-truststore.jks
  1. With the above certificate configuration, it should be possible to access the proxy service with mutual SSL
  2. To test this, we can use SOAP UI
  3. First configure the keystore and truststore for the project pointing to client-keystore.jks and wso2clienttrustore.jks. Refer the below screenshot

ssl_keystore.png

  1. Then select the keystore as client-keystore.jks in properties. Refer below screenshot
invoke.png



  1. Then service should be able to execute successfully. But before it, following SOAP Fault should seen in the SOAP UI

beforeconfig.png

  1. Sample Mutul SSL SOAP client and REST Client can be found in [1] which written by Asela.

Mutual SSL for REST service

  1. Since certificates are already configured, following steps can be continue without configuring the certificates again.

  1. To configure Mutual SSL in a REST API in WSO2 ESB, it’s required to have a handler configured.
  2. In location [2], it can be found source for the handler which is a modified version of it’s original author Asela.
  3. It’s required to build the project. But location [3] contains already built jar(org.soasecurity.apim.authentication.handler-1.0.0.jar) which need to be deploy in {ESB_HOME}/repository/components/lib folder of ESB.
  4. Then create a API with following API definition


<?xml version="1.0" encoding="UTF-8"?>
<api context="/test" name="Test">
  <resource methods="GET" protocol="https" uri-template="/value/{tag}">
     <inSequence>
        <payloadFactory media-type="json">
           <format>{"Status":"OK"}</format>
           <args />
        </payloadFactory>
        <log>
           <property name="JSON-Payload" value="test" />
        </log>
        <property action="remove" name="NO_ENTITY_BODY" scope="axis2" />
        <property name="messageType" scope="axis2" type="STRING" value="application/json" />
        <respond />
     </inSequence>
  </resource>
  <handlers>
     <handler class="org.soasecurity.apim.authentication.handler.MutualSSLAuthenticationHandler" />
  </handlers>
</api>
  1. Above we have configured API with Mutual Authentication Handler which enforce the Mutual SSL authentication
  2. To test the API, it can be used the client in [1] or the modified client which adjust to prepare this sample in [4]
  3. With the client, API should be able to invoke successfully

Information sources taken mainly from [5] and [6] which are written by Asela and Hasitha.:)


[3] - https://svn.wso2.org/repos/wso2/people/harsha/mutual-ssl-hander/target/
[5] - http://tryitnw.blogspot.com.es/2015/06/setting-up-mutual-ssl-in-wso2-esb-and.html

[6] - http://xacmlinfo.org/2015/06/02/securing-apis-using-mutual-ssl-with-wso2-api-manager/