Web Container Authentication via LDAP
Table of Contents
- Planning your use case
- Environment Setup for this tutorial
- LDAP Server Configuration
- LDAP Configuration and Directory Information Tree
- Get to know about access control
- Tomcat Configuration
- bind mode v.s. comparison mode
- Editing Tomcat server.xml
- Open your Tomcat configuration file
- Add JNDI Realm Element
- JNDIRealm Configuration Samples
- OpenLDAP Server
- Configuration for Active Directory
- JSPWiki Configuration
- LDAP groups and wiki groups
- Editing JSPWiki web.xml
- Updating jspwiki.properties
- Update JSPWiki security policy
- References
Planning your use case#
By Default, JSPWiki uses XML user database files for authentication. This is good for small standalone applications but in enterprise environments, user accounts are centrally stored in systems like Active Directory, Lotus Domino, LDAP Servers (i.e.: OpenLDAP, Sun One Directory Server, etc.). So in an enterprise environment, you can use an LDAP service to manage your wiki users and groups. If you are running Tomcat as your servlet container, you can configure your JSPWiki to use Tomcat JNDIRealm feature so that LDAP users can log into JSPWiki system without any additional efforts.In order to achieve this, you need to have enough information about your LDAP environment, Tomcat configuration details, and JSPWiki application web.xml. You need several steps to make this happen:
- Setup a working LDAP Server if you don't already have one.
- Change the configuration of tomcat to work with LDAP
- Change the configuration of JSPWiki to let LDAP users log in successfully
Environment Setup for this tutorial#
LDAP Server | OpenLDAP Server 2.3.43 (cygwin) | |
---|---|---|
Tomcat | Tomcat 6.0.30 | |
JSPWiki | JSPWiki 2.8.4 | |
LDAP Directory Information |
|
LDAP Server Configuration#
If you do not have a working LDAP server, you can install from scratch. There are lot of LDAP servers you can choose from, open source or commercial. OpenLDAP is one of the most popular LDAP Servers. You can get the latest build, docs from its website: http://www.openldap.org
LDAP Configuration and Directory Information Tree#
You need to have some entries on your LDAP instance, both users and groups. You need to get the following information about your LDAP server and directory information. Please consult your LDAP administrator if you don't know.Item | Note | Example |
---|---|---|
LDAP Host | LDAP server host name or IP address | localhost |
LDAP Port | 389 for ldap:// (default value) 636 for ldaps:// (default value) | |
Base DN | The root DN of your DIT. All the entries are created under this entry. | dc=example,dc=com |
User Base | The DN where all your user entries are created | ou=people,dc=example,dc=com |
Group Base | The DN where all group entries are created | ou=groups,dc=example,dc=com |
root DN | The DN of the administrator. This may be used later | cn=Manager,dc=example,dc=com |
root DN password | Password for the admin |
If all your users and groups are created under the same parent entry, use the same parent DN for group base and user base.
Get to know about access control#
Try to get the current configuration for LDAP access control. This is quite useful for later debugging. The following is an example of ACL definition in OpenLDAP. You can use it as a template.access to dn.sub="ou=groups,dc=example,dc=com" by self write by * read access to dn.base="" by * read access to dn.base="cn=Subschema" by * read access to * by self write by users read by anonymous search
Where:
- For entries under ou=groups,dc=example,dc=com, read access is granted to roles except self. Anonymous user can read group members under this configuration
- For other entries, the currently logged in user can edit entries of their own. Other authenticated users can read the values while anonymous only has search privilege.
Tomcat Configuration#
The LDAP support is implemented by JNDIRealm in Tomcat. You can add a Realm element to your Tomcat server.xml file. You can add the node in the XML elements below:- Inside an <Engine> element - This Realm will be shared across ALL web applications on ALL virtual hosts, UNLESS it is overridden by a Realm element nested inside a subordinate <Host> or <Context> element.
- Inside a <Host> element - This Realm will be shared across ALL web applications for THIS virtual host, UNLESS it is overridden by a Realm element nested inside a subordinate <Context> element.
- Inside a <Context> element - This Realm will be used ONLY for THIS web application.
For more information about Tomcat Realm and JNDIRealm, please refer to Tomcat 6.0 documentation http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html.
bind mode v.s. comparison mode#
Tomcat can use either bind mode or comparison mode for authenticating user. You need to make the right choice for this.
This configuration in this tutorial uses bind mode for now. Comparison mode configuration is not available.
For detailed information about these two modes, please check Tomcat documentation: http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#JNDIRealm
Editing Tomcat server.xml #
In this tutorial, the JNDIRealm will be added inside <Engine> element.Open your Tomcat configuration file#
Tomcat configuration file server.xml is located in <CATALINA_HOME>/conf. Open it with your favourite text editor. Go to the XML section below Engine/Realm. You can find there by looking for text below:<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
Add JNDI Realm Element#
Add one extra Realm element just after the UserDatabase node. The XML fragment of JNDIRealm configuration is like below:<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" connectionURL="ldap://localhost:389" userPattern="cn={0},ou=people,dc=example,dc=com" roleBase="ou=groups,dc=example,dc=com" roleSubtree="true" roleSearch="(member={0})" roleName="cn" roleNested="true" />
where
- connectionURLThe LDAP server connection w/ port. The template is (ldap://|ldaps://)<LDAP_Host>[:<LDAP_Port]>.
- userPattern The DN pattern for LDAP users. This attribute can be used for case like all users are stored under the same parent entry. {0} will be replaced with each user's actual login.
- roleBase Base DN of your group base
- roleSubtree Search sub entries if enabled.
- roleSearch the LDAP search filter for selecting role entries. It optionally includes pattern replacements "{0}" for the distinguished name(i.e.:(uid=user,ou=People, dc=example,dc=com)) and/or "{1}" for the username of the authenticated user. The attribute name depends on which object class you use for your groups. Here are a few attribute names for common groups:
- member} for objectClass groupOfNames
- uniqueMember objectClass groupOfUniqueNames
- memberUid objectClass posixGroup
- roleName the attribute in a role entry containing the name of that role.
- roleNested enable nested groups. Set to true if you want to nest groups in groups.
JNDIRealm Configuration Samples#
The JNDIRealm configuration is basically the same for most LDAP servers. The variants may be attribute names for user logins, group member attribute names, etc.OpenLDAP Server#
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99" connectionURL="ldap://localhost:389" userPattern="cn={0},ou=people,dc=example,dc=com" roleBase="ou=groups,dc=example,dc=com" roleSubtree="true" roleSearch="(member={0})" roleName="cn" roleNested="true" />
Configuration for Active Directory#
<Realm className="org.apache.catalina.realm.JNDIRealm" connectionURL="ldap://domaincontroller-host:389" connectionName="CN=Ldaplogin,OU=EDP Login,OU=All Users XP,DC=poison,DC=in" connectionPassword="***secret***" userBase="OU=All Users XP,DC=domain" userSubtree="true" userSearch="(userPrincipalName={0}@yourdomain.com)" userRoleName="memberOf" roleBase="CN=Groups,DC=domain" roleName="cn" roleSubtree="true" roleSearch="(member={0})" />
userSearch="(sAMAccountName={0})"
I am currently trying to figure out a way to authenticate through domain trusts. -JoergMeyer
JSPWiki Configuration#
Now that your Tomcat can start work with your LDAP, the next step is to configure JSPWiki for LDAP authentication through Tomcat.LDAP groups and wiki groups#
You can also map LDAP groups to wiki groups if you want to enforce JSPWiki ACL to LDAP user groups. You need to change the web.xml to include your wanted groups if you want to use LDAP groups. You can do so by assigning proper privileges to LDAP groups in your JSPWiki policy file.Editing JSPWiki web.xml#
Open your wiki's web.xml in an editor, and uncomment the CONTAINER-MANAGED AUTH section like below:
<security-constraint> <web-resource-collection> <web-resource-name>Administrative Area</web-resource-name> <url-pattern>/Delete.jsp</url-pattern> </web-resource-collection> <auth-constraint> <role-name>wiki-admin</role-name> </auth-constraint> <!-- <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>Authenticated area</web-resource-name> <url-pattern>/Edit.jsp</url-pattern> <url-pattern>/Comment.jsp</url-pattern> <url-pattern>/Login.jsp</url-pattern> <url-pattern>/NewGroup.jsp</url-pattern> <url-pattern>/Rename.jsp</url-pattern> <url-pattern>/Upload.jsp</url-pattern> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>HEAD</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <web-resource-collection> <web-resource-name>Read-only Area</web-resource-name> <url-pattern>/attach</url-pattern> <http-method>DELETE</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint> <role-name>wiki-admin</role-name> <role-name>wiki-users</role-name> </auth-constraint> <!-- <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/LoginForm.jsp</form-login-page> <form-error-page>/LoginForm.jsp</form-error-page> </form-login-config> </login-config> <security-role> <description> This logical role includes all authenticated users </description> <role-name>wiki-users</role-name> </security-role> <security-role> <description> This logical role includes all administrative users </description> <role-name>wiki-admin</role-name> </security-role>
- wiki-admin is the LDAP group whose members will have the wiki admin privileges
- wiki-users is the LDAP group whose members will be normal authenticated wiki users.
I commented the user-data-constraint section since I failed to enable SSL in tomcat.
Updating jspwiki.properties#
You need to uncomment the WebContainerAuthorizer property to use web container authorization. See below# AUTHORIZATION (EXTERNAL) # For authorization, JSPWiki has a two-tier system. When we want to # determine whether a user has permission to perform a certain action, # we first consult an external "authorizer" to determine if the user # is a member of the required role. By default, JSPWiki uses the # servlet container's authorization service for this (that is, it # calls HttpServletRequest.isUserInRole(String) ). # However, you can use another Authorizer if you wish; specify that # class here. jspwiki.authorizer =com.ecyrd.jspwiki.auth.authorize.WebContainerAuthorizer
Update JSPWiki security policy#
If you would like to set permissions to LDAP groups, you can simply add policy entries on authorize.Role. The following is an entry for wiki-admin group (from LDAP).grant principal com.ecyrd.jspwiki.auth.authorize.Role "wiki-admin" { permission com.ecyrd.jspwiki.auth.permissions.AllPermission "*"; };
References#
- http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html
- http://www.openldap.org/doc/admin24/access-control.html
Add new attachment
Only authorized users are allowed to upload new attachments.
List of attachments
Kind | Attachment Name | Size | Version | Date Modified | Author | Change note |
---|---|---|---|---|---|---|
png |
ldap_tree_structure.png | 10.7 kB | 1 | 31-Oct-2011 08:22 | David Gao | LDAP Directory Information Tree |