Showing posts with label user store. Show all posts
Showing posts with label user store. Show all posts

Tuesday, January 14, 2014

How to read properties file from custom UserStoreManager

Scenario

You have developed a XUserStoreManager extending an inbuilt userstoremanager implemetation (i.e. ActiveDirectoryUserStoreManager).

You need to read some configuration files from a property file, which you do not want embed in the XUserStoreManager.jar which is deployed in <IS_HOME>/repository/components/dropins


What is the best approach:

1. You can put your custom properties in <IS_HOME>/repository/conf/user-mgt.xml inside your <CustomUserStoreManager> section as below.
<Property name="customProperty">customValue</Property>

2. Put properties withing your CustomUserStoreManager configuration section. Then you can access your properties as below as in [1]

i.e.

String patterns = realmConfig.getUserStoreProperty(LDAPConstants.USER_DN_PATTERN); 

Applicable : WSO2IS-4.6.0

[1] - https://svn.wso2.org/repos/wso2/carbon/kernel/branches/4.0.0/core/org.wso2.carbon.user.core/4.0.2/src/main/java/org/wso2/carbon/user/core/ldap/ReadOnlyLDAPUserStoreManager.java

Tuesday, June 18, 2013

Connecting to Active Directory in READ-ONLY mode

When connecting to AD in readOnly mode we need to use the configuration used for "External LDAP as the user store in READ ONLY mode", which is commented in usermgmt.xml by default.

We also need to set values for admin role to connect to Active Directory Server
 <AdminRole>admin</AdminRole>
                <AdminUser>
                     <UserName>support</UserName>
                     <Password>XXXXXX</Password>
                </AdminUser>

In here we need to specify a user who exists in our active directory server. He need not be the administrator user of the AD server. This user will be the admin user of the carbon server. We need not to specify the password here. It can be left as 'XXXX'.

This admin user must be in the user search base ("UserSearchBase") that is configured in user store manager configuration.

In the UserStore configuration also we need to update the properties to match the connecting active directory server.
        <UserStoreManager class="org.wso2.carbon.user.core.ldap.ReadOnlyLDAPUserStoreManager">
            <Property name="ReadOnly">true</Property>
            <Property name="MaxUserNameListLength">100</Property>
            <Property name="ConnectionURL">ldap://10.100.3.131:389</Property>
            <Property name="ConnectionName">CN=Administrator,CN=Users,DC=wso2,DC=test</Property>
            <Property name="ConnectionPassword">pass#word1</Property>
            <Property name="passwordHashMethod">PLAIN_TEXT</Property>
            <Property name="UserSearchBase">CN=Users,DC=wso2,DC=test</Property>
            <Property name="UserNameListFilter">(objectClass=person)</Property>
            <Property name="UserNameAttribute">cn</Property>
            <Property name="ReadLDAPGroups">true</Property>
            <Property name="GroupSearchBase">CN=Users,DC=wso2,DC=test</Property>
            <Property name="GroupNameListFilter">(objectClass=groupOfNames)</Property>
            <Property name="GroupNameAttribute">cn</Property>
            <Property name="MembershipAttribute">member</Property>
            <Property name="UserRolesCacheEnabled">true</Property>
            <Property name="ReplaceEscapeCharactersAtUserLogin">true</Property>
           <Property name="maxFailedLoginAttempt">0</Property>   
           <Property name="Referral">throw</Property>
           <Property name="DomainName">wso2</Property>
        </UserStoreManager>UserRolesCacheEnabled

i) ConnectionURL
This should have the format of ldap://<AD host-ip>:<AD_listen_port>

In failing to connect to AD server you might get this error [E1]

If you need to validate the listen port you can use portqry utility which is a command-line tool troubleshoot TCP/IP connectivity issues.  Use following command to validate if the port is open and listening:
portqry -n <hostIP> -p udp -e 389
If it resolves the port to the LDAP service, it sends an unformatted user datagram to UDP port 389 on the target system. More Infor [1]


ii) ConnectionName 
This should specify an account that can browse and search your active directory user and group bases. Also this need to be given using relative distinguished names. For an example my ConnectionName is 'CN=Administrator,CN=Users,DC=wso2,DC=test'. How this was worked out is: DC is to demote DNS Name (prefixed as Domain Component). So my DNS name is wso2.test. This makes up DC=wso2,DC=test.

Then in my domain Component, Users directory resides in the root and I have 'Administrator' user in there. So the user account and the folder highrachy to reach it can be made up as: CN=Administrator,CN=Users

So this makes us: ConnectionName=CN=Administrator,CN=Users,DC=wso2,DC=test

You are most likely to get this error [E2] when there is a misconfiguration in this.

iii) ConnectionPassword 
Is the password of above user (Administrator's password in my case)

iv) UserSearchBase
This also should be specified using distinguished name. It should be the folder which should be searched for the users.

v) UserNameAttribute
The attribute used to name users

vi) GroupSearchBase
Distinguished name of the object that holds the groups. In my case it is 'Users'.

v) ReadLDAPGroups
- This property is related to <AdminRole> configurations.
1. If "ReadLDAPGroups" is set to true, This role can be a role from AD, If this role is in the group search based ("GroupSearchBase"). Then <AdminUser> must be assigned to this role from the AD level.

2. If "ReadLDAPGroups" is set to false. Then this role can be an internal role of Carbon.Then while starting server, role is created as internal role and assigned <AdminUser> to it. This mapping kept internally in the user mgt database


[1] - http://support.microsoft.com/kb/816103

[E1] -
[2013-06-18 13:54:18,002] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} -  Error obtaining connection for the second time10.100.3.131:10389
javax.naming.CommunicationException: 10.100.3.131:10389 [Root exception is java.net.ConnectException: Connection timed out]
    at com.sun.jndi.ldap.Connection.<init>(Connection.java:223)
    at com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:136)
    at com.sun.jndi.ldap.LdapClientFactory.createPooledConnection(LdapClientFactory.java:64)
    .
    .
    .
    .
    .
Caused by: java.net.ConnectException: Connection timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:337)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:198)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
    at java.net.Socket.connect(Socket.java:579)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.<init>(Socket.java:425)
    at java.net.Socket.<init>(Socket.java:208)
    at com.sun.jndi.ldap.Connection.createSocket(Connection.java:365)
    at com.sun.jndi.ldap.Connection.<init>(Connection.java:200)
    ... 47 more



[2] -
2013-06-18 15:29:11,484] ERROR {org.wso2.carbon.user.core.ldap.LDAPConnectionContext} -  Error obtaining connection. [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
javax.naming.AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903AA, comment: AcceptSecurityContext error, data 525, v1771]
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3087)
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3033)
    .
    .

Friday, November 18, 2011

Connecting WSO2 G-Reg to a secured & confidential external user store

From Carbon 3.2.0 onwards we have an embeded LDAP user store which is accessible via port 10389 in default settings. The server also configurable to use LDAP to connect to an external user store. If we need this user store to be secured and confidential it need to be configured to connect via LDAPS.

In this post I will be demonstrating how to connect WSO2 G-REg 4.0.0 to an external user store which will be accessed via secured transport (where the tracffic is transmitted via secured transport).

As pre-requisites we will need WSO2 G-REG 4.0.0 installation which you can download from here. Also we need Apache Directory Server which, we will be using as the LDAP server. You should also have JDK 1.5 or above installed.

With pre-requisites ready, we simply have to follow the steps given below.

Step 1:
Firstly you need to install WSO2 G-Reg 4.0.0 which can be downloaded from here. Extract the .zip file to a location of your preference.

Step 2:

As I mentioned earlier also WSO2 G-Reg is already configured with an internal LDAP user store. In order to connect to an external user store we need to disconnet the existing connection. To achieve this we need to uncomment 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.

<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.
 <Property name="enable">true</Property>


Step 3:
Now we need to enable configurations for the externanal LDAP server. But lets wait until we configure our user store as we still don't have those details with us.

Step 4:
Now we need to install Apache Directry Studio. You can download the .zip ditribution, unzip and use it. The other choice is to use the binary installer. In my case I used the binary installer. I was taken through an installation wizard which prompted me to set locations for the inatalltion, instances and where to keep the startup, who is the default user etc.


Step 5:
Lets enable SSL in ADS. you need to navigate to ADS_INSTANCE_HOME/default/conf/ and open server.xml. Here search for 'tcpTransport address' and check if SSL is enabled. It is enabled by default. If not you need to update with this.
 


Step 6:
In this setup I am going to use a signed certificate to use in our LDAPS communitcation. I will be using keytool to generate the required keystore and certificates.

Since am going have my LDAP server setup with an SSL server certificate, I must obtain a signed certificate for the server. To achieve this I will be using java keytool and create a self signed certificate (a public/private key pair).

 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 What is the 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:


Step 7:
After this we need to update the LDAP server (apacheDS) configuration to use our keystore files. to do this navigate to ADS_INSTANCE_HOME/default/conf/ and open server.xml. Update "keystoreFile" in following segment;

<ldapServer id="ldapServer"
            allowAnonymousAccess="false"
            saslHost="ldap.example.com"
            saslPrincipal="ldap/ldap.example.com@EXAMPLE.COM"
            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">

After this restart Apache DS server. In my case will restart it via /etc/init.d (/etc/init.d/ldap restart;)

After the restart we can verify the connections using an LDAP browser. Lets use ApacheDirectoryStudio-linux-x86_64-1.5.2.v20091211.

Step 8:
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.

To ensure G-Reg trusts the certificate used by the LDAP server we must install them in G-REGs trust store. So lets export the certificate using keystore.
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 this certificate to G-Reg's trust store like this:
 keytool -import -file carbon_server.cer -alias carbon_server -keystore /home/yumani/Documents/support/320/JPMDEVSPRT-31/wso2greg-4.0.0/repository/resources/security/client-truststore.jks -storepass wso2carbon
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:
Now that we have configured the LDAP server we need to setup and add user entries to the directory server. The guide (http://fusesource.com/docs/broker/5.3/security/LDAP-AddUserEntries.html) will show you how to complete this task.

Step 10:
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 as [1] you will need to update "UserSearchBase" property to include ou=users as well:
     <Property name="UserSearchBase">ou=users,ou=system</Property>

 
Final step:
Alright we have everything set, lets start WSO2 G-Reg server and acces the user store.

Start carbon server as below;
wso2server.sh -Djavax.net.ssl.trustStore=/path/to/carbon/repository/resources/security/client-truststore.jks -Djavax.net.ssl.trustStorePassword=wso2carbon

Access G-Reg admin console from https://localhost:9443/


Login to the server using admin credentials (admin/admin) as specified in usermgmt.xml

You may navigate to Configure > Users and Roles > Users and see that the user store is connected!!!

Featured

Selenium - Page Object Model and Action Methods

  How we change this code to PageObjectModel and action classes. 1 2 3 driver . findElement ( By . id ( "userEmail" )). sendKeys (...

Popular Posts