Spring Security and LDAP

From OpenNMS
Jump to: navigation, search

Abstract

Centralized authentication is a "big deal" in any enterprise environment. Integrating your OpenNMS implementation with your environment is a Good Thing. Before linking the two, there are some considerations. The main one is if you want to rely solely on your central authenticator for all OpenNMS auth events, or support a hybrid scheme of the built-in local (aka UserDAO) as well as an LDAP or similar authenticator. Keep in mind that OpenNMS, itself, has processes periodically authenticating (think RTC and Provisioning) and for this reason it is better to go the loosely-coupled route by continuing to support the UserDAO mechanism.

Another source of minutiae lies in the specific LDAP implementation you're working with. While AD and OpenLDAP (and Sun DS, etc.) implement the same protocol, their schemas are substantially different. The biggest difference is the memberOf attribute, which is not supported by default LDAP v3 spec (and is not present in common OpenLDAP installs), but comes standard with AD. This has a significant implication in that you cannot filter a user search by supplementary group membership, and most installs tend not to be fully hierarchical (User's DN doesn't cite a home group). Fortunately, you can either create dedicated per-role LDAP groups or map existing groups to roles by selecting and configuring the appropriate AuthoritiesPopulator. A 'role' is how OpenNMS refers to an access level, btw.

Changes to this article's structure

This article had reached the point of being mostly a repository for people's useful modifications to the OpenNMS webapp's applicationContext-spring-security.xml file. Those examples can now be found in External Authentication Recipes. This page's edit history is also available for review.

Configuring external authentication

The OpenNMS webapp uses Spring Security for its user authentication, authorization, and accounting (AAA) concerns. Configuring external authentication therefore really amounts to configuring Spring Security correctly for your own environment.

From OpenNMS 1.12.6 onward, the Spring Security configuration can be modified by the user without making large, invasive changes to the main context file. Here is a summary of the files involved:

OPENNMS_HOME/jetty-webapps/
|-- opennms
|   |-- WEB-INF
|   |   |-- applicationContext-spring-security.xml
|   |   |-- spring-security.d
|   |   |   |-- activeDirectory.xml.disabled
|   |   |   |-- ldap.xml.disabled
|   |   |   `-- radius.xml.disabled

Many other files are omitted for brevity.

applicationContext-spring-security.xml 
The main Spring Security context configuration file for the OpenNMS webapp. A small edit (described below) is required to switch on external authentication.
spring-security.d 
Directory containing example files for common use cases. You must copy one of these files to a name of your own choosing, as long as it ends in .xml, and edit its details as outlined below.
activeDirectory.xml.disabled 
Skeleton file to configure LDAP authentication against an EXAMPLE.ORG Active Directory domain
ldap.xml.disabled 
Skeleton file to configure authentication LDAP against an example.org generic schema
radius.xml.disabled 
Skeleton file to configure authentication against a RADIUS server as an alternative to LDAP

Along with copying one of the files in the spring-security.d subdirectory to have a .xml extension and editing its contents to describe your directory configuration, you'll need to uncomment a single XML element in the applicationContext-spring-security.xml file. Here's the part that needs changing:

    <!-- To enable external (e.g. LDAP, RADIUS) authentication, uncomment the following.
         You must also rename and customize exactly ONE of the example files in the
         spring-security.d subdirectory. -->
    <!-- <authentication-provider ref="externalAuthenticationProvider" /> -->

And here is how it needs to look when you're done:

    <!-- To enable external (e.g. LDAP, RADIUS) authentication, uncomment the following.
         You must also rename and customize exactly ONE of the example files in the
         spring-security.d subdirectory. -->
    <authentication-provider ref="externalAuthenticationProvider" />

Anatomy of an LDAP configuration

Whether the authentication source is an Active Directory, a Novell eDirectory, or some other LDAP-enabled directory, the basic components (expressed as beans in Spring Framework lingo) that need to exist and be configured are the same:

ldapTemplate 
In this bean, configure your LDAP server URL(s) and search base
authenticationSource 
The username and password to use for the initial LDAP server "bind" operation are specified here.
userSearch 
Tells Spring Security how to find and authenticate users in the directory specified in the ldapTemplate bean.
userGroupLdapAuthoritiesPopulator 
Tells Spring Security how to authorize users (once the userSearch has authenticated them) to access various parts of the OpenNMS webapp.
externalAuthenticationProvider 
Ties together all the other beans in the file for use by Spring Security.

After uncommenting the externalAuthenticationProvider bean reference in applicationContext-spring-security.xml and creating your site-specific configuration file (with a .xml extension) in the 'spring-security.d subdirectory, you must restart OpenNMS for the changes to take effect. Before doing this, it's a good idea to check that your changes have not led to malformed XML files:

xmllint --noout applicationContext-spring-security.xml spring-security.d/*.xml

If this command produces no output, then the XML files are well-formed. If you've gotten all the details right, you'll be able to log in to the webapp with your directory credentials after restarting OpenNMS.