Wednesday, October 3, 2007

JBoss Portal with OpenSSO and OpenDS (step by step howto)

Update: Please check http://www.jboss.org/community/wiki/JBossPortalandOpenSSO for JBoss Portal 2.7.2 and a OpenSSO integration using REST API

Our latest release JBoss Portal 2.6.2 comes with built in support for several SSO frameworks. The goal of this post is to provide step by step instructions on how to integrate JBoss Portal with OpenSSO. In addition OpenDS LDAP server is used as a user store for both of them.

OpenSSO project is hosted on java.net community page and as its homepage states: "is based on the code base of Sun JavaTM System Access Manager,". Based on an open sourced proprietary product, OpenSSO is quite rich in features unfortunately since the product launch it doesn't have had any stable release yet. You need to use the nightly builds, the source code repository and the open mailing lists. It also really suffers from a lack of documentation. Because of that JBoss Portal support should be considered as experimental for the moment and community driven. As the OpenSSO codebase is not yet stable, the configuration and deployment details explained below could change in future.

It is important to mention that the initial code and instructions on how to integrate OpenSSO with JBoss Portal 2.4 (previous major release) were contributed by Vincenzo Di Nino in our wiki (thanks for the contribution!). Configuration of OpenSSO with OpenDS was described in Indira's blog.

  1. System setup

    1. OpenSSO may not operate well if you want to test it on your local machine and refer to 'localhost'. To workaround that you can give your local machine valid FQDN. Edit your /etc/host file and add:

      127.0.0.1 www.domain.com localhost.localdomain localhost


      Now you'll be able to refer to it using "http://www.domain.com" in your browser.

  2. LDAP server
    1. Download OpenDS - in this example we'll use "OpenDS-1.0.0-build004".

    2. Unzip it and run setup script. OpenDS comes with GUI you can use for configuration. To use a command line you can add "--cli" parameter. Configure OpenDS as follows:

      [bdaw@localhost OpenDS]$ unzip -q OpenDS-1.0.0-build004.zip
      [bdaw@localhost OpenDS]$ cd OpenDS-1.0.0-build004
      [bdaw@localhost OpenDS-1.0.0-build004]$ ./setup --cli
      OpenDS Directory Server 1.0.0-build004

      Please wait while the setup program initializes...

      On which port would you like the Directory Server to accept connections from
      LDAP clients?
      [389]: 8389

      What would you like to use as the initial root user DN for the Directory
      Server?
      [cn=Directory Manager]:

      Please provide the password to use for the initial root user: password
      Please re-enter the password for confirmation: password

      What do you wish to use as the base DN for the directory data?
      [dc=example,dc=com]: dc=opensso,dc=java,dc=net
      Options for populating the database:
      1. Only create the base entry
      2. Leave the database empty
      3. Import data from an LDIF file
      4. Load automatically-generated sample data

      Database population selection:
      [1]: 4


      Please specify the number of user entries to generate:
      [2000]:


      Applying the requested configuration to the Directory Server...
      Successfully wrote the updated Directory Server configuration
      Importing the LDIF data into the Directory Server database...
      [26/Sep/2007:15:41:39 +0200] category=JEB severity=INFORMATION msgID=8388697 msg=Starting import (using 8 threads)
      [26/Sep/2007:15:41:39 +0200] category=JEB severity=INFORMATION msgID=8388766 msg=Processing LDIF
      [26/Sep/2007:15:41:42 +0200] category=JEB severity=INFORMATION msgID=8388767 msg=End of LDIF reached
      [26/Sep/2007:15:41:44 +0200] category=JEB severity=INFORMATION msgID=8388730 msg=Beginning final index merge
      [26/Sep/2007:15:41:48 +0200] category=JEB severity=INFORMATION msgID=8388732 msg=Final index merge complete (processing time 3 seconds)
      [26/Sep/2007:15:41:48 +0200] category=JEB severity=INFORMATION msgID=8388702 msg=Processed 2002 entries, imported 2002, skipped 0, rejected 0 and migrated 0 in 8 seconds (average rate 233.3/sec)
      [26/Sep/2007:15:41:48 +0200] category=JEB severity=INFORMATION msgID=8388703 msg=Number of index values that exceeded the entry limit: 0
      Import complete
      The OpenDS setup process has completed successfully


      By selecting "Load automatically-generated sample data" option you'll start with 2000 random generated user entries in your LDAP server.
    1. Copy "98-opends_user_schema.ldif" and "99-am_sm_ds_schema.ldif" files into "OpenDS-1.0.0-build004/config/schema/" folder. Those configuration files comes from Indira Blog and will extend OpenDS schema to enable cooperation with OpenSSO. According to OpenSSO mailing lists it should support OpenDS out of box in the future.
    2. Start OpenDS by running:

      [bdaw@localhost OpenDS-1.0.0-build004]$ ./bin/start-ds
      [26/Sep/2007:17:41:29 +0200] category=CORE severity=NOTICE msgID=458886 msg=OpenDS Directory Server 1.0.0-build004 starting up
      [26/Sep/2007:17:41:39 +0200] category=CONFIG severity=NOTICE msgID=3605006 msg=Access control has been enabled and will use the org.opends.server.authorization.dseecompat.AciHandler implementation
      [26/Sep/2007:17:41:43 +0200] category=JEB severity=NOTICE msgID=8847402 msg=The database backend userRoot containing 2002 entries has started
      [26/Sep/2007:17:41:44 +0200] category=CORE severity=NOTICE msgID=458887 msg=The Directory Server has started successfully
      [26/Sep/2007:17:41:44 +0200] category=CORE severity=NOTICE msgID=458891 msg=The Directory Server has sent an alert notification generated by class org.opends.server.core.DirectoryServer (alert type org.opends.server.DirectoryServerStarted, alert ID 458887): The Directory Server has started successfully


      You can also use "status-panel" binary which provide GUI for managing OpenDS state.
    3. Add following ldif file into OpenDS (it is also based on ldif from Indira Blog):

      dn: ou=agents,dc=opensso,dc=java,dc=net
      objectClass: top
      objectClass: organizationalUnit

      dn: ou=groups,dc=opensso,dc=java,dc=net
      objectClass: top
      objectClass: organizationalUnit

      dn: ou=dsame users,dc=opensso,dc=java,dc=net
      objectClass: top
      objectClass: organizationalUnit

      dn: cn=dsameuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      objectclass: inetuser
      objectclass: organizationalperson
      objectclass: person
      objectclass: top
      cn: dsameuser
      sn: dsameuser
      userPassword: secret12

      dn: cn=amldapuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      objectclass: inetuser
      objectclass: organizationalperson
      objectclass: person
      objectclass: top
      cn: amldapuser
      sn: amldapuser
      userPassword: secret123

      dn:dc=opensso,dc=java,dc=net
      changetype:modify
      add:aci
      aci: (target="ldap:///dc=opensso,dc=java,dc=net")(targetattr="*")(version 3.0; acl "S1IS special dsame user rights for all under the root suffix"; allow (all) userdn = "ldap:///cn=dsameuser,ou=DSAME Users,dc=opensso,dc=java,dc=net"; )

      dn:dc=opensso,dc=java,dc=net
      changetype:modify
      add:aci
      aci: (target="ldap:///dc=opensso,dc=java,dc=net")(targetattr="*")(version 3.0; acl "S1IS special ldap auth user rights"; allow (read,search) userdn = "ldap:///cn=amldapuser,ou=DSAME Users,dc=opensso,dc=java,dc=net"; )

      To do this you can use "ldapmodify" tool that comes with OpenDS:

      [bdaw@localhost OpenDS-1.0.0-build004]$ ./bin/ldapmodify -a -h localhost -p 8389 -D "cn=Directory Manager" -w password -f opensso_entries.ldif
      Processing ADD request for ou=agents,dc=opensso,dc=java,dc=net
      ADD operation successful for DN ou=agents,dc=opensso,dc=java,dc=net
      Processing ADD request for ou=groups,dc=opensso,dc=java,dc=net
      ADD operation successful for DN ou=groups,dc=opensso,dc=java,dc=net
      Processing ADD request for ou=dsame users,dc=opensso,dc=java,dc=net
      ADD operation successful for DN ou=dsame users,dc=opensso,dc=java,dc=net
      Processing ADD request for cn=dsameuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      ADD operation successful for DN cn=dsameuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      Processing ADD request for cn=amldapuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      ADD operation successful for DN cn=amldapuser,ou=DSAME Users,dc=opensso,dc=java,dc=net
      Processing MODIFY request for dc=opensso,dc=java,dc=net
      MODIFY operation successful for DN dc=opensso,dc=java,dc=net
      Processing MODIFY request for dc=opensso,dc=java,dc=net
      MODIFY operation successful for DN dc=opensso,dc=java,dc=net

      Another good tool for LDAP operations you can leverage for this task is LDAP Browser.

  1. OpenSSO deployment and installation

    1. Download OpenSSO. It is distributed as a single war file that can be easily deployed in a servlet container. On the project page you'll find nightly builds ready for download. We'll use build 20070509 here. Just obtain "amclientsdk.jar" and "opensso.war"
    2. Download and unzip tomcat - we'll use "apache-tomcat-5.5.25" binary here.
    3. Edit file "apache-tomcat-5.5.25/conf/server.xml" and change default HTTP connector port to 8081:

      <Connector port="8081" maxHttpHeaderSize="8192"
      maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
      enableLookups="false" redirectPort="8443" acceptCount="100"
      connectionTimeout="20000" disableUploadTimeout="true" />


      Comment out AJP connector:

      <!--<Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />-->

    4. Put "opensso.war" file into "webapps" directory and run tomcat:

      [bdaw@localhost Tomcat]$ cd apache-tomcat-5.5.25
      [bdaw@localhost apache-tomcat-5.5.25]$ cp ../../OpenSSO/20070905/opensso.war webapps/
      [bdaw@localhost apache-tomcat-5.5.25]$ cd bin/
      [bdaw@localhost bin]$ chmod a+x *.sh
      [bdaw@localhost bin]$ ./startup.sh

    5. Put http://www.domain.com:8081/opensso/ in your browser to see the OpenSSO configuration page:


    6. Click "Enter only the password" option to perform quick file system based configuration and follow the instructions. Let's use "password" value to keep it simple :)



    7. After clicking on "Login to the administration console" you should be able to authenticate into OpenSSO console using "amadmin" user and password provided in previous step.



  2. OpenDS datastore configuration

    1. Now you need to configure OpenSSO to use OpenDS as its user store. Click on the "opensso" realm and then go to the "Data Stores" tab.
    2. Click "New", put "opends" as name, select "Sun DS with AM schema" radio button and press "Next"
    3. Change values of the following fields:
      LDAP Server: localhost:8389
      LDAP Bind Password: secret12 (This is specified in ldif you added with ldapmodify to OpenDS previously)
      LDAPv3 Plug-in Supported Types and Operations: Remove "filteredrole" and "role" values
      and click "Finish"
    4. Go to the "Subjects" tab. If "opends" DataStore is configured properly you should see many user entries that were autogenerated during OpenDS configuration.



    5. Click on "New" and create 3 user entries:
      ID: amadmin Password: password
      ID: admin Password: admin
      ID: user Password: user



    6. Go to the "Authentication" tab and in "Module Instances" section click on "LDAP"
    7. Correct the value of "Primary LDAP Server" to "localhost:8389" and for "Password for Root User Bind:" use "secret123" (This is specified in ldif you added with ldapmodify to OpenDS previously). Click on "Save" and "Back to Authentication"
    8. In "Authentication Chaining" section click on "ldapService", change required instance from "DataStrore" to "LDAP" and click on "Save".



    9. Now you can verify that everything is correctly configured. Logout and click on "Return to Login page". You should see "This server uses LDAP Authentication" and be able to authenticate as
      User name: amadmin
      Password: password



  3. JBoss Portal authentication with OpenSSO

    1. Deploy JBoss Portal 2.6.2 on JBoss Application Server 4.2.1 using standard instructions - you can use the ready to go bundle here (use "JBoss Portal + JBoss AS 4.2.1").
    2. Edit "jboss-4.2.1.GA/server/default/deploy/jboss-portal.sar/portal-server.war/WEB-INF/context.xml" file and uncomment following lines:

      <Valve className="org.jboss.portal.identity.sso.opensso.OpenSSOAuthenticationValve"
      loginURL="http://www.domain.com:8081/opensso"
      logoutURL="http://www.domain.com:8081/opensso/UI/Logout"
      appendLoginGoto="true"
      appendLogoutGoto="true"
      authType="FORM"
      />



      (Make sure that "loginURL" and "logoutURL" parameters contain hostname proper for your configuration and port on which tomcat instance with OpenSSO is running)

    3. Copy "amclientsdk.jar" file that you downloaded from OpenSSO site to "jboss-4.2.1.GA/server/default/deploy/jboss-portal.sar/lib"
    4. OpenSSO configuration should create file named "AMConfig.properties" in your home directory. Copy this file into "jboss-4.2.1.GA/server/default/config". Edit it and change line:

      com.iplanet.am.serverMode=true

      to

      com.iplanet.am.serverMode=false

    5. Run JBoss Application server and go to portal URL : http://www.domain.com:8080/portal

      Now you can verify the configuration. On the main JBoss Portal page click on "Login" link in the upper right corner. You'll be redirected to the OpenSSO login page. After successfull authentication (user: admin password: admin) you'll be redirect back to the portal. Now try to click on "Logout" link. Then go to http://www.domain.com:8081/opensso page and login again as user: admin password: admin. Now browse again to http://www.domain.com:8080/portal. You are authenticated! Is it magic? No! Its SSO ;)

      After those steps JBoss Portal is configured to authenticate using OpenSSO login page and to auto discover SSOToken presence in the upcoming requests. Based on this token it will auto authenticate users. However JBoss Portal is still using database to store and retreive users. This means that to be able to leverage some of portal features based on users identity and profile information, you'll need to keep users in both OpenSSO DataStore and JBoss Portal database.

      So now lets move this one step further. OpenSSO uses OpenDS LDAP server to store users so why not configure JBoss Portal to use the same LDAP server?

  4. JBoss Portal with OpenDS
    1. Add following ldif to OpenDS.

      dn: cn=Admin,ou=groups,dc=opensso,dc=java,dc=net
      objectClass: top
      objectClass: groupOfNames
      cn: Admin
      description: Portal admin role
      member: uid=admin,ou=People,dc=opensso,dc=java,dc=net

      dn: cn=User,ou=groups,dc=opensso,dc=java,dc=net
      objectClass: top
      objectClass: groupOfNames
      cn: User
      description: Portal user role
      member: uid=admin,ou=People,dc=opensso,dc=java,dc=net
      member: uid=user,ou=People,dc=opensso,dc=java,dc=net


      Save ldif above to the "portal_entries.ldif" file and use following command:

      [bdaw@localhost OpenDS-1.0.0-build004]$ ./bin/ldapmodify -a -h localhost -p 8389 -D "cn=Directory Manager" -w password -f portal_entries.ldif

    1. Edit "jboss-4.2.1.GA/server/default/deploy/jboss-portal.sar/jboss-portal.sar/META-INF/jboss-service.xml" and change line:

      conf/identity/identity-config.xml

      to

      conf/identity/ldap_identity-config.xml

    2. Edit "jboss-4.2.1.GA/server/default/deploy/jboss-portal.sar/conf/identity/ldap_identity-config.xml" and change it as follows:

      <datasources>
      <datasource>
      <name>LDAP</name>
      <config>
      <option>
      <name>host</name>
      <value>localhost</value>
      </option>
      <option>
      <name>port</name>
      <value>8389</value>
      </option>
      <option>
      <name>adminDN</name>
      <value>cn=Directory Manager</value>
      </option>
      <option>
      <name>adminPassword</name>
      <value>password</value>
      </option>
      </config>
      </datasource>
      </datasources>


      .....


      <module>
      <type>User</type>
      <implementation>LDAP</implementation>
      <class>org.jboss.portal.identity.ldap.LDAPExtUserModuleImpl</class>
      <config/>
      </module>
      <module>
      <type>Role</type>
      <implementation>LDAP</implementation>
      <class>org.jboss.portal.identity.ldap.LDAPExtRoleModuleImpl</class>
      <config/>
      </module>

      ....

      <option-group>
      <group-name>common</group-name>
      <option>
      <name>userCtxDN</name>
      <value>ou=People,dc=opensso,dc=java,dc=net</value>
      </option>
      <option>
      <name>userSearchFilter</name>
      <value><![CDATA[(&((uid={0})(objectClass=person)))]]></value>
      </option>
      <option>
      <name>roleCtxDN</name>
      <value>ou=groups,dc=opensso,dc=java,dc=net</value>
      </option>
      <option>
      <name>roleSearchFilter</name>
      <value><![CDATA[(&((cn={0})(objectClass=groupOfNames)))]]></value>
      </option>
      </option-group>


    3. Run JBoss Application server and go to the portal URL : http://www.domain.com:8080/portal
    4. Click on "Login" link and authenticate as user: admin password: admin
    5. Click on "Admin" link in upper right corner and go to "Members" tab


      Pay attention to the "Registered users 2002" information :)

    6. Click on the "Search Users" link and enjoy the view:

      Now you can play with it more on your own. Go to the OpenSSO administration console (you must login as "amadmin"), try to add another user subject and use it to authenticate to the portal.

Note:
OpenSSO creates its configuration files in your home directory by default. You'll find "AMConfig.properties" file and "opensso" and "AccessManager" directories there. If you start playing with the deployment from scratch its important to remove them or you will get stucked wondering why OpenSSO configuration page doesn't come up with fresh installation....


8 comments:

JeanV said...

This is very interesting. Are there any instructions for doing the same with CAS?

Boleslaw Dawidowicz said...

Yes. Look at JBoss Portal Reference Guide:

http://docs.jboss.com/jbportal/v2.6.2/referenceGuide/html/sso.html

gaurav said...

Hi. It's quite interesting.
But I am facing a problem in this. Once the user is authenticated through openSSO, its again asking for jboss portal authentication and if i enter the credentials its null and not able to login to the portal.
Also can you tell whether you have used some policy agent for this application.
Can you help me out.

Rammy said...

Hi im using JBoss portal for my devolpement. i have configured so that registered members are stored in the LDAP. but i also need those users to be saved in Database as well.can you help me on this issue.

this is to sync the LDAP and DB. awaiting help

Thanh said...

Remember increase Tomcat memory heap = 1000MB for example or you will be failed while configuring

prashant said...

after changing the authentication module from Data Store to LDAP, the amadmin logic fails. This has been posted as an issue in sun site. Any thoughts how to overcome this?

Mike said...

The LDAP connectivity doesn't seem to work with OpenSSO 8.0.

Ajay said...

Hi,

I am working on one project which needs siteminder to protect JBOSS Portal via Apapche Reverse proxy.Will you be able to help with the approach?

Regards,
Ajay.
+91-9819734737