HomeDocumentation > Reference > Samples > Java EE sample applications > ldap-sample-app - LDAP Sample Application
{scrollbar}

top

This sample shows how you can use a Lightweight Directory Access Protocol (LDAP) server to configure and control access to resources on your Geronimo server.

There are two routes to running this sample. You can either use the Apache Geronimo plugin (version 1.0) for the Apache Directory Service 1.5.1 or you can use an external LDAP server.

One way to install the Apache Geronimo-Apache Directory Server Plugin is by navigating in the Geronimo Administration Console to Applications -> Plugins. Once in the view, updating the repository list (which should add a repository for your installed Geronimo version if not already included), selecting the referenced repository, and then select Show Plugins in selected repository to display the list of all possible plugins in this directory. Locate the Apache Geronimo-Apache Directory Server Plugin and then install it. Source for this plugin can be found at Geromino Directory Plugin Source.

NOTE: The Apache Geronimo-Apache Directory plugin can not be installed in Geronimo 2.1.2. If you are using Geronimo 2.1.2 with this sample you must use an external LDAP server. However, the Apache Geronimo-Apache Directory plugin can be installed in Geronimo 2.1.3 and this sample works equally well with the Geronimo 2.1.3.

Geronimo uses the Apache Directory Server for its directory service, this is part of the Apache Directory Project. Geronimo implements the following two projects from the ApacheDS project.

  • ApacheDS Core
    Server's core contains all backend subsystems. It depends on protocol and uses it with seda to service Lightweight Directory Access Protocol (LDAP) requests. The core contains the JNDI provider, interceptor framework, interceptor services, the schema subsystem and the database subsystem. Hence the core is the heart of the server.
  • ApacheDS Shared
    Created to eliminate cyclic project dependencies between the core and the maven plug-in. Any code shared across modules in general can go here so long as it does not depend on other modules.

More information about these two projects can be found at the ApacheDS project URL:
http://directory.apache.org/subprojects/apacheds/projects/index.html

At this point in time, the Geronimo plugin only provides LDAP viewing capabilities, editing is not there yet but adding this feature is in plan for the next releases of Geronimo. You will have to use an external LDAP client such as ldapbrowser/editor, jxplorer or gq for editing the configurations of the Directory Server in Geronimo.

The other alternative is to use Geronimo with an external LDAP server. For example, you may download Apache Directory Service binary, start the ldap server and load it up with the ldap-sample.ldif givenand follow the rest of the sample instructions.

This article is organized in the following sections:

3

Starting the LDAP server

If you installed the Apache Geronimo-Apache Directory Plugin it should have been started as part of the installation. You can verify that it is started from command line using the deployer tool or via the Geronimo Administration Console.

Using the Administration Console click on System Modules on the navigation menu from the left and look for the component name org.apache.geronimo.plugins/directory in the Installed System Modules portlet. You will see the current status and available commands for this particular component.

Alternatively, if you are using an external LDAP server, start that server in the normal manner and follow the remaining instructions here.

Back to Top

Source Code for Sample

Please reference Samples General Information for information on obtaining and building the source for this and other samples.

At this point you can choose to install an LDAP client and import/export an .ldif file to a directory server. However, this is not required. Directions are provided if you choose to not install an LDAP client.

Back to Top

Add LDAP entries

Ensure that Geronimo is up and running and the Directory service is started.

To add entries manually

When you installed the Apache Geronimo-Apache Directory plugin you may have noticed a message on the console similar to the following:

solid WARN [ServerContextFactory] LDIF load directory '/Users/user1/geronimo-tomcat6-javaee5-2.1/var/ldif' does not exist. No LDIF files will be loaded.

This is because the directory server does not yet have any content. You can manually add the content necessary for the sample by including the ldap-sample.ldif from the sample source in the location specified in the message (<geronimo-home>/var/ldif/) and restarting the Geronimo server or optionally just the directory configuration in the server.

To add entries using an LDAP client

Start your LDAP client and create a new connection profile with the following values:

Host:

<localhost>

Port:

10389

Base DN:

ou=system

User DN:

uid=admin,ou=system

Password:

secret

Once you connect to the Geronimo Directory server you will see the initial configuration, this configuration can be exported as a backup in a ldif file. Depending the LDAP client you are using the export/import steps will be different. For example, to export the initial configuration using the ldapsearch tool execute the following command:

ldapsearch -h localhost -p 10389 -b "ou=system" -D "uid=admin,ou=system" -w secret -x "(objectclass=*)"

When you export the initial configuration you get an ldif file with a content similar as the one shown in the following example.

export.ldifsolid dn: ou=system ou: system objectClass: organizationalUnit objectClass: top dn: uid=admin, ou=system displayName: Directory Superuser uid: admin userPassword:: c2VjcmV0 objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top sn: administrator cn: system administrator dn: ou=users, ou=system ou: users objectClass: organizationalUnit objectClass: top dn: ou=groups, ou=system ou: groups objectClass: organizationalUnit objectClass: top dn: ou=configuration, ou=system ou: configuration objectClass: organizationalUnit objectClass: top dn: ou=partitions, ou=configuration, ou=system ou: partitions objectClass: organizationalUnit objectClass: top dn: ou=services, ou=configuration, ou=system ou: services objectClass: organizationalUnit objectClass: top dn: ou=interceptors, ou=configuration, ou=system ou: interceptors objectClass: organizationalUnit objectClass: top dn: prefNodeName=sysPrefRoot, ou=system objectClass: extensibleObject prefNodeName: sysPrefRoot

Now you need to import the entries needed to run the sample application. Packaged with the sample application is a sample .ldif file with all the entries necessary to run the LDAP sample application, this file is located in <ldap_home>/ldap-sample.ldif. To import the data with ldapmodify tool execute the following command:

ldapmodify -h localhost -p 10389 -D "uid=admin,ou=system" -w secret -x -a -f <ldap_home>/ldap-sample.ldif

The following example shows the content of the ldap-sample.ldif file.

ldap-sample.ldifsolid # User: system dn: uid=system,ou=users,ou=system cn: John Doe sn: Doe givenname: John objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson ou: Human Resources ou: People l: Las Vegas uid: system mail: system@apachecon.comm telephonenumber: +1 408 555 5555 facsimiletelephonenumber: +1 408 555 5556 roomnumber: 4613 userPassword: manager # User: user1 dn: uid=user1,ou=users,ou=system cn: User sn: One givenname: User1 objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson ou: Human Resources ou: People l: Las Vegas uid: user1 mail: user1@apachecon.comm telephonenumber: +1 408 555 5555 facsimiletelephonenumber: +1 408 555 5556 roomnumber: 4613 userPassword: p1 # User: user2 dn: uid=user2,ou=users,ou=system cn: User sn: Two givenname: User2 objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson ou: Human Resources ou: People l: Las Vegas uid: user2 mail: user2@apachecon.comm telephonenumber: +1 408 555 5555 facsimiletelephonenumber: +1 408 555 5556 roomnumber: 4613 userPassword: p2 # Group: admin dn: cn=admin,ou=groups,ou=system objectClass: groupOfUniqueNames uniqueMember: uid=system,ou=users,ou=system uniqueMember: uid=user2,ou=users,ou=system cn: admin # Group: guest dn: cn=guest,ou=groups,ou=system objectClass: groupOfUniqueNames uniqueMember: uid=user1,ou=users,ou=system cn: guest

Once the file is imported you should get a confirmation that five entries were successfully imported.

Back to Top

Deploy the LDAP realm

One way to install the LDAP realm for the sample is by installing a Geronimo plugin created for this purpose. You can do this by navigating in the Geronimo Administration Console to Applications -> Plugins. Once in the view, updating the repository list (which should add http://geronimo.apache.org/plugins/geronimo-2.1/ if not already included), selecting the referenced repository, and then select Show Plugins in selected repository to display the list of all possible plugins in this directory. Locate the Geronimo Samples :: ldap-sample-app :: security realm and then install it. However, this process hides many of the details of creating and installing the realm. For those details refer to the next section.

LDAP realm deployment details

The LDAP sample application provides a security realm that needs to be deployed before the deployment of the application itself. This realm is located in <ldap_home>/ldap-realm.xml and the content is illustrated in the following example.

xmlldap-realm.xmlsolid <module xmlns="http://geronimo.apache.org/xml/ns/deployment-1.2"> <environment> <moduleId> <groupId>console.realm</groupId> <artifactId>LDAP_Sample_Realm</artifactId> <version>1.0</version> <type>car</type> </moduleId> </environment> <gbean name="LDAP_Sample_Realm" class="org.apache.geronimo.security.realm.GenericSecurityRealm" xsi:type="dep:gbeanType" xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <attribute name="realmName">LDAP_Sample_Realm</attribute> <reference name="ServerInfo"> <name>ServerInfo</name> </reference> <xml-reference name="LoginModuleConfiguration"> <log:login-config xmlns:log="http://geronimo.apache.org/xml/ns/loginconfig-1.2"> <log:login-module control-flag="REQUIRED" wrap-principals="false"> <log:login-domain-name>LDAP_Sample_Realm</log:login-domain-name> <log:login-module-class>org.apache.geronimo.security.realm.providers.LDAPLoginModule</log:login-module-class> <log:option name="initialContextFactory">com.sun.jndi.ldap.LdapCtxFactory</log:option> <log:option name="connectionURL">ldap://localhost:10389</log:option> <log:option name="connectionUsername">uid=admin,ou=system</log:option> <log:option name="connectionPassword">secret</log:option> <log:option name="authentication">simple</log:option> <log:option name="userBase">ou=users,ou=system</log:option> <log:option name="userSearchMatching">uid={0}</log:option> <log:option name="userSearchSubtree">false</log:option> <log:option name="roleBase">ou=groups,ou=system</log:option> <log:option name="roleName">cn</log:option> <log:option name="roleSearchMatching">(uniqueMember={0})</log:option> <log:option name="roleSearchSubtree">false</log:option> </log:login-module> <log:login-module control-flag="OPTIONAL" wrap-principals="false"> <log:login-domain-name>LDAP_Sample_Realm-Audit</log:login-domain-name> <log:login-module-class>org.apache.geronimo.security.realm.providers.FileAuditLoginModule</log:login-module-class> <log:option name="file">var/log/login-attempts.log</log:option> </log:login-module> </log:login-config> </xml-reference> </gbean> </module>

This deployment plan tell Geronimo all the connection and search parameters against the LDAP database. This plan also specifies to record each login attempt into the login-attempts.log log file.

To deploy the ldap-realm.xml run the following command from the <geronimo_home>/bin directory:

java -jar deployer.jar --user system --password manager deploy <ldap_home>/ldap-realm.xml

Once deployed you should see a confirmation message similar to the following example:

solid D:\geronimo-tomcat6-jee5-2.0\bin>deploy deploy \samples\2.0\ldap-sample-app\ldap-realm.xml Using GERONIMO_BASE: D:\geronimo-tomcat6-javaee5-2.1.2 Using GERONIMO_HOME: D:\geronimo-tomcat6-javaee5-2.1.2 Using GERONIMO_TMPDIR: D:\geronimo-tomcat6-javaee5-2.1.2\var\temp Using JRE_HOME: C:\Java\jdk1.5.0_06\\jre Deployed console.realm/LDAP_Sample_Realm/1.0/car

Back to Top

For further details refer to the LDAP Realm section.

Creating and Installing the LDAP Sample Application

One way to install the LDAP sample application is by installing a Geronimo plugin created for this purpose. You can do this by navigating in the Geronimo Administration Console to Applications -> Plugins. Once in the view, updating the repository list (which should add http://geronimo.apache.org/plugins/geronimo-2.1.2/ if not already included), selecting the referenced repository, and then select Show Plugins in selected repository to display the list of all possible plugins in this directory. Locate the Geronimo Configs :: LDAP Sample for Tomcat or Geronimo Configs :: LDAP Sample for Jetty (depending upon you Geronimo service choice) and then install it. However, this process hides many of the details of creating and installing the sample. For those details refer to the next section.

Deployment plans

There is a common deployment plan that is used for the sample. The unprocessed version of this plan is at ldap-sample-app/ldap-sample-app-jetty/src/main/plan/plan.xml. The processed version shown here with plugin name and all dependencies filled in can be found at ldap-sample-app/ldap-sample-app-jetty/target/resources/META-INF/plan.xml after building the project.

xmlplan.xmlsolid <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.2"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"> <dep:moduleId> <dep:groupId>org.apache.geronimo.samples</dep:groupId> <dep:artifactId>ldap-sample-app-jetty</dep:artifactId> <dep:version>2.1.2</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>org.apache.geronimo.samples</dep:groupId> <dep:artifactId>ldap-sample-app-realm</dep:artifactId> <dep:version>2.1.2</dep:version> <dep:type>car</dep:type> </dep:dependency> <dep:dependency> <dep:groupId>org.apache.geronimo.configs</dep:groupId> <dep:artifactId>jasper</dep:artifactId> <dep:version>2.1.2</dep:version> <dep:type>car</dep:type> </dep:dependency> <dep:dependency> <dep:groupId>org.apache.geronimo.configs</dep:groupId> <dep:artifactId>jetty6</dep:artifactId> <dep:version>2.1.2</dep:version> <dep:type>car</dep:type> </dep:dependency> </dep:dependencies> <dep:hidden-classes/> <dep:non-overridable-classes/> </dep:environment> <context-root>/LDAP_Sample</context-root> <security-realm-name>LDAP_Sample_Realm</security-realm-name> <security> <default-principal realm-name="LDAP_Sample_Realm"> <principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="system"/> </default-principal> <role-mappings> <role role-name="content-administrator"> <realm realm-name="LDAP_Sample_Realm"> <principal class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" name="admin" designated-run-as="true"/> <principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="system"/> </realm> </role> <role role-name="guest"> <realm realm-name="LDAP_Sample_Realm"> <principal class="org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal" name="guest" designated-run-as="true"/> <principal class="org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal" name="user1"/> </realm> </role> </role-mappings> </security> </web-app>

Most of the deployment plan is straight forward. However, the security configuration is tricky. The <security-realm-name> is described in the <security> element through a sequence of declarations in each <realm> element.

While the web.xml specifies the security roles, the plan.xml maps to which specific users or groups in the Geronimo security realms they belong to. If there is a user that is not logged in, it defaults to what is defined in the <default-principal> element.

There are two roles that are issued in this project: content-administrator and guest. And they each hold two principals: a GeronimoGroupPrincipal and a GeronimoUserPrincipal. Since the 'designated-run-as' flag is turned on for some principals, they will be the ones used if the deployable has a run-as role set in the web.xml.

Note that these role mappings will be overridden by the actual roles (what users pertaining to what groups) defined in the LDAP server. Ultimately it is the realm defined in the application deployment plan who determines the validation method. Nevertheless, for this particular example, you still need to define principals and role mappings as determined in the XML schemas

Back to Top

The web.xml deployment descriptor shown in the following example (also located in the <ldap_home>/WEB-INF diretory) adds security constraints based on the location of the files.

xmlweb.xmlsolid <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Admin Role</web-resource-name> <url-pattern>/protect/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>content-administrator</role-name> </auth-constraint> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>No Access</web-resource-name> <url-pattern>/forbidden/*</url-pattern> </web-resource-collection> <auth-constraint/> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>ldap-realm-1</realm-name> <form-login-config> <form-login-page>/auth/logon.html?param=test</form-login-page> <form-error-page>/auth/logonError.html?param=test</form-error-page> </form-login-config> </login-config> <security-role> <role-name>content-administrator</role-name> </security-role> </web-app>

Back to Top

Package the sample application

You can build the war alone from within the ldap-sample-app-war directory and issuing the following command:

mvn clean install

This command will package all the existing files and directories inside <ldap_home>. Although not needed inside the .war file, the ldap-realm.xml and ldap-sample.ldif files will also be included.

Back to Top

Deploy the sample application

It's easiest to deploy the appropriate Geronimo plugin for your specific server image (either tomcat or jetty). This will deploy the sample application with the Geronimo deployment plan specified earier. However, you can optionally choose to deploy the war with the appropriate deployment plan. To deploy the LDAP sample application in this fashion, make sure the Geronimo server is up and running. Open a command line window, change directory to <geronimo_home>/bin and run the following command:

java -jar deployer.jar --user system --password manager deploy <ldap_home>/ldap-demo.war <deployment_plan_home>/plan.xml

Testing the sample application

Once the Web application is successfully deployed you should see a confirmation message similar as the one shown in the following example:

solid D:\geronimo-tomcat6-jee5-2.0\bin>deploy deploy \samples\2.0\ldap-sample-app\ldap-demo.war Using GERONIMO_BASE: D:\geronimo-tomcat6-javaee5-2.1.2 Using GERONIMO_HOME: D:\geronimo-tomcat6-javaee5-2.1.2 Using GERONIMO_TMPDIR: D:\geronimo-tomcat6-javaee5-2.1.2\var\temp Using JRE_HOME: C:\Java\jdk1.5.0_06\\jre Deployed samples/LDAP_Sample/1.2/war @ http://localhost:8080/LDAP_Sample

To test the LDAP application open a Web browser and access the following URL:

http://localhost:8080/LDAP_Sample

The following figure shows the welcome page for the LDAP sample application.

Click on Protect to validate against the LDAP Directory Server.

Enter system as the username and manager as the password and click Login. The username and password you provide here is the same you use to access the Geronimo Web console and it is stored in the Directory Server database. Once you are logged in you should see the following screen.

At this point you have an application that is validating username and passwords against an LDAP Directory Server database based on the security configuration you provided earlier in the LDAP realm. Now, if you go back to the welcome page and click on Forbidden you should receive a 403 - Forbidden HTTP error similar to the one shown in the following figure.

Depending on the web container you are using (that is Jetty or Tomcat) the presentation of that screen may be slightly different.

To further test this example you could now try the different users provided in the ldap-sample.ldif, use your LDAP client and add/remove users from the different groups. You will notice the changes immediatly (you may need to close your web browser).

Back to Top