2011/11/29
29 Nov, 2011

Connecting WSO2 G-Reg to a Secured & Confidential External User Store

  • Yumani Ranaweera
  • Director Customer Success - WSO2

 

Introduction

In WSO2 Governance Registry (G-Reg) V4.0.0 we have an embedded LDAP user store which is accessible via port 10389 in default settings. In the same release it is also possible to configure LDAP to connect to an external user store. The external user store can be anything such as Apache Directory Server, Active Directory Server etc. When connecting to an external user store there can be a concern on the level of security given to data. In such cases most common solution is secured transmission. So in this scenario also if we need our user store to be secured and confidential we can configure it to connect via LDAPS instead of LDAP.

In this tutorial I will be demonstrating how to connect WSO2 G-Reg 4.0.0 to an external user store which is going to be accessed through secured transport where the traffic is transmitted across secured transport.

Applies to:

WSO2 Carbon Servers 3.2.0

 

Pre-requisites:

  • Apache DS as the LDAP server
  • JDK1.5 and above

 

Step 1 : Install WSO2 G-Reg

As the first step you need to install WSO2 G-Reg 4.0.0. We can download the released version from here. Once downloaded, extract the .zip file to a location of your preference. In the proceeding steps, we will be referring the location of extracted wso2greg-4.0.0 folder  as 'GREG_HOME'.

 

Step 2 : Disable the internal LDAP user store

As I mentioned at the beginning, WSO2 G-Reg is already configured with an internal LDAP user store. In order to connect to an external user store we need to disconnect the existing connection. To do this we need to uncomment relevant settings from usermgmt.xml and embedded-ldap.xml. These files reside in GREG_HOME/repository/conf folder.

Lets do these changes like this : In usermgt.xml comment the default user store manager configuration which is given like below. As you may notice this has "ReadOnly" set to false. In other words this is a read\write enabled user store. Lets disable this now, to allow an external user store to be connected. Also you see that the ports are accessed vi a parameters. The actual values for these are set in carbon.xml which is available in GREG_HOME/repository/conf folder.

<UserStoreManager class="org.wso2.carbon.user.core.ldap.ApacheDSUserStoreManager">
            <Property name="ReadOnly">false</Property>
            <Property name="ConnectionURL">ldap://localhost:${Ports.EmbeddedLDAP.LDAPServerPort}</Property>
            <Property name="ConnectionName">uid=admin,ou=system</Property>
            <Property name="ConnectionPassword">admin</Property>
            <Property name="passwordHashMethod">SHA</Property>
            <Property name="UserNameListFilter">(objectClass=person)</Property>
            <Property name="UserEntryObjectClass">wso2Person</Property>
            <Property name="UserSearchBase">ou=Users,dc=wso2,dc=org</Property>
            <Property name="UserNameSearchFilter">(&amp;(objectClass=person)(uid=?))</Property>
            <Property name="UserNameAttribute">uid</Property>
            <Property name="PasswordJavaScriptRegEx">[\\S]{5,30}</Property>
            <Property name="UsernameJavaScriptRegEx">[\\S]{3,30}</Property>
            <Property name="UsernameJavaRegEx">^[^~!@#$;%^*+={}\\|\\\\&lt;&gt;]{3,30}$</Property>
            <Property name="RolenameJavaScriptRegEx">[\\S]{3,30}</Property>
            <Property name="RolenameJavaRegEx">^[^~!@#$;%^*+={}\\|\\\\&lt;&gt;]{3,30}$</Property>
            <Property name="ReadLDAPGroups">true</Property>
            <Property name="WriteLDAPGroups">true</Property>
            <Property name="EmptyRolesAllowed">true</Property>
            <Property name="GroupSearchBase">ou=Groups,dc=wso2,dc=org</Property>
            <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
            <Property name="GroupEntryObjectClass">groupOfNames</Property>
            <Property name="GroupNameSearchFilter">(&amp;(objectClass=groupOfNames)(cn=?))</Property>
            <Property name="GroupNameAttribute">cn</Property>
            <Property name="MembershipAttribute">member</Property>
<UserStoreManager>

 

In embedded-ldap.xml you need to set "enabled" property in "EmbeddedLDAP" to false. This file is also available in GREG_HOME/repository/conf/ folder.

<Property name="enable">true</Property>

 

Step 3 : Enabling external LDAP server

Normally, now we must enable configurations for the external LDAP server. But lets wait until we set up our user store as we still don't have those details of it with us.

 

Step 4 : Install Apache Directory Server

As I mentioned in the beginning we will be using Apache Directory Server as the directory server. There are few easy methods to install this software. You can download the .zip distribution, unzip and use it. The other choice is to use the binary installer. Both can be downloaded from here. In my case I used the binary installer. I was taken through an installation wizard which prompted me to set locations for the installation, instances and where to keep the startup, who is the default user etc. 

Hereafter I will be referring the ADS (Apache Directory Server) home directory as "ADS_INSTANCE_HOME'.

 

Step 5 : Enable SSL in LDAP Server

Lets enable SSL in ADS so the traffic is transmitted via secure transport. To do this you need to navigate to ADS_INSTANCE_HOME/default/conf/ and open server.xml. In server.xml, search for 'tcpTransport address' and check if SSL is enabled. In Apache Directory Server, SSL is enabled by default. If not you need to update the configuration like shown below. In this configuration the SSl port is given as '10636'.

 <tcpTransport address="localhost" port="10636" enableSSL="true"/>

 

Step 6 : Generate self signed certificate for LDAP Server

Since am going have my LDAP server setup with an SSL server certificate, I must obtain a signed certificate for the server. For this purpose I am going to use a self signed certificate and I will be using java keytool to generate the certificate (public/private key pair). Following snippet shows the keytool command that I used along with the responses.

 keytool -genkey -alias carbon_server -keyalg RSA -keystore carbon_server.jks -storepass xxxxxx -validity 730 
  What is your first and last name? 
    [Unknown]:  Yumani Ranaweera
  name of your organizational unit?
    [Unknown]:  QA 
  What is the name of your organization?
    [Unknown]:  WSO2 
  What is the name of your City or Locality? 
    [Unknown]:  Colombo 
  What is the name of your State or Province? 
    [Unknown]:  Western 
  What is the two-letter country code for this unit? 
    [Unknown]:  SL 
  Is CN=Yumani Ranaweera, OU=QA, O=WSO2, L=Colombo, ST=Western, C=SL correct? 
    [no]:  yes 
  
  Enter key password for <carbon_server> 
  (RETURN if same as keystore password):   
  Re-enter new password:  

Now I have a public and private key pair inside a keystore named as carbon_server.jks.   Tip: If you are wondering where the keystore files were created, your carbon_server.jks will be there in the location where you executed the above command from.

 

Step 7 : Configure keystores in LDAP Server

After generating the signed certificates we need to update the LDAP server (ADS) configuration to use our keystore files. To do this navigate to ADS_INSTANCE_HOME/default/conf/ folder and open server.xml. Update "keystoreFile" in following segment; 

 <ldapServer id="ldapServer" 
             allowAnonymousAccess="false" 
             saslHost="ldap.example.com" 
             saslPrincipal="ldap/[email protected]" 
             searchBaseDn="ou=users,ou=system" 
             maxTimeLimit="15000" 
             maxSizeLimit="1000" 
             keystoreFile="/home/yumani/software/LDAP/apacheds-1.5.7_new/external_keystore/carbon_server.jks"  
             certificatePassword="secret"> 

 

Once this is done we need to restart Apache Directory Server. In my test setup I will restart it via /etc/init.d (/etc/init.d/apacheds-1.5.7-default start) since I installed my startup script in /etc/init.d.  After restarting the directory server we can verify its SSL connection using an LDAP browser. A commonly used option is ApacheDirectoryStudio-linux-x86_64-1.5.2.v20091211. . You can download it from here.

 

Step 8 : Update client side (WSO2 G-Reg) to trust the certificate

WSO2 Carbon based products use Java Secure Socket Extension (JSSE) for SSL support. So we need to upgrade JAVA_HOME/jre/lib/security with JSSE provider.  JAVA_HOME is the place where I have my JDK installed.

To ensure tha WSO2 G-Reg trusts the certificate used by the LDAP server we must install them in G-REG server's trust store. So lets export the certificate using keytool.

 keytool -export -keystore carbon_server.jks -alias carbon_server -file carbon_server.cer
            Enter keystore password:  
            Certificate stored in file <carbon_server.cer>

 

Then lets import the above certificate to G-Reg's trust store like this. You will have to replace 'GREG_HOME' with the correct path.

 keytool -import -file carbon_server.cer -keystore GREG_HOME/repository/resources/security/client-truststore.jks
 -storepass wso2carbon -alias carbon_server
         Owner: CN=yumani, OU=qa, O=wso2, L=col, ST=western, C=sl 
         Issuer: CN=yumani, OU=qa, O=wso2, L=col, ST=western, C=sl 
         Serial number: 4eba06d3 
         Valid from: Wed Nov 09 10:21:31 IST 2011 until: Tue Feb 07 10:21:31 IST 2012 
         Certificate fingerprints: 
         MD5:  EB:23:58:74:3B:6A:1B:CC:26:D8:84:AE:D3:A5:AC:4D 
         SHA1: 7F:73:3C:5B:BA:0B:B8:47:69:1E:12:5C:47:EB:D0:E9:C3:08:2E:AB 
         Signature algorithm name: SHA1withRSA 
         Version: 3 
  Trust this certificate? [no]:  yes 
  Certificate was added to keystore 

 

Step 9 : Configure LDAP user store with content

At successful completion of above steps, we have configured a secured LDAP transmission between WSO2 G-Reg and Apache Directory Server. Now we need to setup and add user entries to the directory server. Means we need to add users and groups to the user store. Following is a set of quick steps on how you can do it.

 

Step 10 : Configure WSO2 G-Reg to connect to external LDAP server (Apache Directory Server)

Once the user store is setup we need to configure user manager in WSO2 G-Reg to connnect to it. This is how you do that:

Enable following block in G-REG_HOME/repository/conf/usermgt.xml.

          <UserStoreManager class="org.wso2.carbon.user.core.ldap.ApacheDSUserStoreManager"> 
             <Property name="ReadOnly">false</Property> 
             <Property name="ConnectionURL">ldap://localhost:10389</Property> 
             <Property name="ConnectionName">uid=admin,ou=system</Property> 
             <Property name="ConnectionPassword">secret</Property> 
             <Property name="passwordHashMethod">SHA</Property> 
             <Property name="UserNameListFilter">(objectClass=person)</Property> 
             <Property name="UserEntryObjectClass">inetOrgPerson</Property> 
             <Property name="UserSearchBase">ou=system</Property> 
             <Property name="UserNameSearchFilter">(&amp;(objectClass=person)(uid=?))</Property> 
             <Property name="UserNameAttribute">uid</Property> 
             <Property name="PasswordJavaScriptRegEx">[\\S]{5,30}</Property> 
             <Property name="ReadLDAPGroups">true</Property> 
             <Property name="WriteLDAPGroups">true</Property> 
             <Property name="EmptyRolesAllowed">false</Property> 
             <Property name="GroupSearchBase">ou=system</Property> 
             <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property> 
             <Property name="GroupEntryObjectClass">groupOfNames</Property> 
             <Property name="GroupNameSearchFilter">(&amp;(objectClass=groupOfNames)(cn=?))</Property> 
             <Property name="GroupNameAttribute">cn</Property> 
             <Property name="MembershipAttribute">member</Property> 
         </UserStoreManager> 
   

If you had user store configured according to [1] (Reference section) you will need to update "UserSearchBase" property to include ou=users as well:

      <Property name="UserSearchBase">ou=users,ou=system</Property> 

You also can update the admin user's username and password to an admin user of your preference from Apache Directory Server. This change can be done in following code segment which can be found in usermgmt.xml. In the sample below I have changed the default admin user name and password to match my user base. Remember you should not change <AdminRole> as this is the predefined administrator role for carbon server which has login and administration privileges. You may of course alter the permissions from carbon User Interface after you sign-in to the admin console.

  admin
                
                     yumani
                     yumani
                

Since we are connecting in read/write mode; even if you didn't change this, the G-Reg server will use default setting while writing the default 'admin' user to ADS. If you browse through usermgmt.xml you will find there is another segment similar to above which lets you connect externally via read only mode too. With readonly configuration you will be prompted an error if the specified admin user name password don't match with that of ADS

 

Final Step : Start the Carbon server & experiment user user store

Now we have all the necessary elements on our deployment setup. Lets start WSO2 G-Reg server and access the external user store. You need to start carbon server using the additional parameters given as below;

wso2server.sh -Djavax.net.ssl.trustStore=/path_to_client-truststore.jks -Djavax.net.ssl.trustStorePassword=xxxxxx

In above we have given the path to carbon trust store within '-Djavax.net.ssl.trustStore' and trust store password within '-Djavax.net.ssl.trustStorePassword'.

After the server is successfully started, we can access G-Reg admin console from https://localhost:9443/. You will get usual carbon admin console interface.

 

 

Lets' sign-in to the server using admin credentials. Its yumani/yumani in my test setup. These are the credentials that we specified in usermgmt.xml. To view the contents of the externally connected user user we need to navigate to user management section via Configure > Users and Roles > Users. Under 'Users' you will see the users that we added to out Apache Directory Server. Now! this means we are connected to the external user store.

Since we are connected in read/write mode any changes that you do to users from the carbon admin console will be updated in the external user store and vise versa. Lets do a quick test on this scenario. Given below is a screen print of my users list in ADS.

 

I have two users: yumani, waruna. Now am going to add a third user, 'ashadi', from G-Reg admin console. After adding 'ashadi' lets refresh ADS browser and see. I get the third user updated in directory server too. So this reflects that the changes on G-Reg's admin console are immediately updated in the external user store.

 

 

Summary

In this tutorial I described how to setup WSO2 G-Reg server with an external user store in read/write or read only mode. The transmission used was secured LDAP. While preparing the setup we also learnt how to setup Apache Directory Server for secured data transmission, how to setup a user base in the user store, how to generate trusted certificates and use them.

 

Author

Yumani Ranaweera, Associate Technical Lead, WSO2 Inc

References 

[1] -https://blog.facilelogin.com/2009/04/setting-apache-directory-studio-as-ldap.html

[2] -https://directory.apache.org/apacheds/1.5/33-how-to-enable-ssl.html

[3] -https://research.imb.uq.edu.au/~l.rathbone/ldap/tls.shtml

[4] -https://support.microsoft.com/kb/321051

 

About Author

  • Yumani Ranaweera
  • Director Customer Success
  • WSO2