Using Apache Roller with OpenDS for LDAP authentication

This is a basic guide and is more a set of self-help notes while I learn about LDAP. Even so, at the end of this you’ll have an idea about how to securely authenticate to Roller with user account information held in an OpenDS LDAP directory.

We are using OpenDS v2.2, and an OpenSolaris system running Apache Roller as described in detail in my post here. This how-to assumes you have a freshly installed instance of Roller as described in that link, and have created the initial Roller administrator account with a username of “admin”.

 

Install OpenDS v2.2

The OpenDS installer is a thing of beauty, and a model for how easy software download and installation could be. Matter of fact, with its built-in Java monitoring and administration control panels, the whole package is pretty darn cool.

Go to http://www.opends.org/ and click the “Get 2.2″ now!” link. (make sure you have a recent JRE installed and a decent internet connection).

You’ll be presented with the OpenDS QuickSetup Welcome screen. We want to install a new server instance:

OpenDS QuickSetup Welcome screen

Enter your installation path, and under “LDAP Secure Access”, click the “Configure…” button; in the following screen enable SSL access, and generate a self-signed certificate. All other settings are fine at their defaults:

OpenDS Server Settings

OpenDS configure SSL

We want a standalone server:

OpenDS standalone server

For our Directory Data, the default Directory Base DN of dc=example,dc=com is fine. We also only want to create the base entry for now:

OpenDS Directory Data

Review the settings, and click “Finish” to complete. Once OpenDS has worked its magic, launch the OpenDS control panel, and select the local server instance to manage:

OpenDS installation finished

OpenDS control panel login

 

Create LDAP account information in OpenDS

We’ll now quickly populate our OpenDS directory with some very basic user information.

In the OpenDS Control Panel main view, click the “Directory Data” disclosure arrow on the left-hand of the window, and select “Manage Entries”. In the “Manage Entries” window that appears, select “Entries” on the menu bar, then select “New Organizational Unit”. Name the new OU “People”:

OpenDS - create People OU

Select the newly created “People” OU, and from the “Entries” menu, select “New User…”. Enter the information as follows, noting that the value for “User ID” (UID) will be the same as the Roller account username (in this case, the initial Roller administrator account):

OpenDS - create an admin user

Create additional entries in the same way if you like:

OpenDS - create additional users

 

Import the OpenDS SSL certificate into the system and Glassfish domain keystores

We are setting this up with secure connections all ’round, so Roller needs to trust OpenDS by using OpenDS’ certificate. When installing OpenDS, we generated a self-signed certificate – so we simply locate this and import it into the relevant keystores. We use the keytool command to do this.

I’ve installed OpenDS to /opt/OpenDS, so the OpenDS keystore is located at /opt/OpenDS/config/keystore.

The location of the keystores for the system, and for the Glassfish domain containing the instance of Roller are located respectively at:

/usr/java/jre/lib/security/cacerts
/var/appserver/domains/domain1/config/cacerts.jks

 

Let’s view the contents of the OpenDS keystore:

$ pfexec keytool -list -v -keystore /opt/OpenDS/config/keystore
Enter keystore password:  

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: server-cert
Creation date: 3/05/2010
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=afterburner, O=OpenDS Self-Signed Certificate
Issuer: CN=afterburner, O=OpenDS Self-Signed Certificate
Serial number: 
Valid from: Mon May 03 16:38:02 NZST 2010 until: Wed May 02 16:38:02 NZST 2012
Certificate fingerprints:
	 MD5:  
	 SHA1: 
	 Signature algorithm name: SHA1withRSA
	 Version: 3

 

Now, export the OpenDS certificate to a file:

$ pfexec keytool -export -alias "server-cert" \
-keystore /opt/OpenDS/config/keystore -file /tmp/server-cert.cer
Enter keystore password:  
Certificate stored in file /tmp/server-cert.cer

 

Then import the exported certificate into the Java system keystore:

$ pfexec keytool -import -v -trustcacerts -alias "server-cert" \
-keystore /usr/java/jre/lib/security/cacerts -file /tmp/server\-cert.cer 
Enter keystore password:  
Owner: CN=afterburner, O=OpenDS Self-Signed Certificate
Issuer: CN=afterburner, O=OpenDS Self-Signed Certificate
Serial number: 
Valid from: Mon May 03 16:38:02 NZST 2010 until: Wed May 02 16:38:02 NZST 2012
Certificate fingerprints:
	 MD5:  
	 SHA1: 
	 Signature algorithm name: SHA1withRSA
	 Version: 3
Trust this certificate? [no]:  yes
Certificate was added to keystore
[Storing /usr/java/jre/lib/security/cacerts]

 

And do the same for the Glassfish Roller domain keystore:

$ pfexec keytool -import -v -trustcacerts -alias "server-cert" \
-keystore /var/appserver/domains/domain1/config/cacerts.jks \
-file /tmp/server\-cert.cer 
Enter keystore password:  
Certificate already exists in system-wide CA keystore under alias server-cert
Do you still want to add it to your own keystore? [no]:  yes
Certificate was added to keystore
[Storing /var/appserver/domains/domain1/config/cacerts.jks]

 

 

Configure Roller for LDAP authentication

This involves modifications to the Roller security.xml file to enable LDAP logins, as well as a small change to the roller-custom.properties file. The security.xml file is located (on my system) at /opt/Roller/webapp/roller/WEB-INF. Let’s modify this file first.

 

Under the AUTHENTICATION section of security.xml I’ve added /roller-ui/user.do*=register to the value list for the filterInvocationInterceptor bean. Then under the authenticationManager bean I’ve commented out daoAuthenticationProvider and uncommented ldapAuthProvider.

A copy of this section of my security.xml file follows; hover your mouse over the top-right of the box and select “view source” for the full view:


    <!-- ======================== AUTHENTICATION ======================= -->
    
    <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
         <property name="objectDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /roller-ui/login-redirect**=admin,editor
                /roller-ui/profile**=admin,editor
                /roller-ui/createWeblog**=admin,editor
                /roller-ui/menu**=admin,editor
                /roller-ui/authoring/**=admin,editor
                /roller-ui/admin/**=admin
                /roller-ui/user.do*=register
                /rewrite-status*=admin
            </value>
                <!-- Add this to above list for LDAP/SSO configuration -->
                <!-- /roller-ui/user.do*=register -->
        </property>
    </bean>

    <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <!-- <ref local="daoAuthenticationProvider"/> -->
                <ref local="ldapAuthProvider"/>
                <!-- Uncomment this for CAS/SSO configuration <ref local="casAuthenticationProvider"/> -->
                <ref local="anonymousAuthenticationProvider"/>                
                <!-- rememberMeAuthenticationProvider added programmatically -->
            </list>
        </property>
    </bean>

 

Next, proceed to the LDAP AUTHENTICATION section of security.xml, and uncomment the sample block of code visible there. Most of the code is fine as-is, but we set the constructor-arg value for the initialDirContextFactory bean to the URL/BaseDN of our LDAP server, and the values for managerDn and managerPassword to our OpenDS directory administrator username and password respectively.

A copy of this section of my security.xml file follows; hover your mouse over the top-right of the box and select “view source” for the full view:


    <!-- ===================== LDAP AUTHENTICATION ==================== -->

    <bean id="initialDirContextFactory" class="org.acegisecurity.ldap.DefaultInitialDirContextFactory">
        <constructor-arg value="ldaps://localhost:1636/dc=example,dc=com"/>
        <property name="managerDn" value="cn=Directory Manager"/>
        <property name="managerPassword" value="somepassword"/>
    </bean>
   
    <bean id="ldapUserSearch" class="org.acegisecurity.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg index="0" value=""/>
        <constructor-arg index="1" value="uid={0}"/>
        <constructor-arg index="2" ref="initialDirContextFactory"/>         
        <property name="searchSubtree" value="true"/>           
    </bean>     
    
    <bean id="ldapAuthProvider" class="org.acegisecurity.providers.ldap.LdapAuthenticationProvider">
        <constructor-arg>
            <bean class="org.acegisecurity.providers.ldap.authenticator.BindAuthenticator">
                <constructor-arg ref="initialDirContextFactory"/>
                <property name="userSearch" ref="ldapUserSearch"/>
            </bean>
        </constructor-arg>
        <constructor-arg ref="jdbcAuthoritiesPopulator"/>
        <property name="userCache" ref="userCache"/>
    </bean>    
    
    <bean id="jdbcAuthoritiesPopulator" class="org.apache.roller.weblogger.ui.core.security.AuthoritiesPopulator">
        <property name="defaultRole" value="register"/>       
    </bean>

 

Now, add the following entry to roller-custom.properties (which resides on my system at /var/appserver/domains/domain1/lib/classes):

users.sso.enabled=true

A shout out to Trey Drake from Sun Microsystems who originally blogged about this at http://blogs.sun.com/treydrake/entry/opends_roller_integration.

 

Log in to Roller using LDAP authentication

The caveat here is that Roller user accounts must already exist for successful LDAP authentication; LDAP+Roller will not provision them automatically, at least not with this simple setup.

Restart the Glassfish Roller domain (and possibly the Roller MySQL database as well for completeness) and you should now be able to log in to Roller with the username admin, using the LDAP password specified when you created the corresponding admin account in OpenDS.

Additional Roller user accounts you create as the Roller admin user (using the Roller admin BUI) can use LDAP for authentication, provided the username you specify for the Roller user account is the same as the UID (User ID) for the corresponding OpenDS entry.

About these ads

One thought on “Using Apache Roller with OpenDS for LDAP authentication

  1. Pingback: Use OpenDS for Thunderbird LDAP Address Book data « Dave Koelmeyer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s