How to authenticate against Microsoft Active Directory Services




This article is about how to authenticate a OpenNMS Horizon against Active Directory Services (ADS) provided on a Microsoft Windows Server 2016. The scope here is on the Active Directory and Spring configuration parts in OpenNMS.

In this example the Active Directory domain is called labmonkeys.local and the Microsoft Windows Server has the IP address The user name for the bind user is OpenNMS Bind User with the password MyPass123!.

We want to have two Active Directory groups, one named OpenNMS-Admins and a second one name OpenNMS-Users.

The users in the group OpenNMS-Users will be able to login to the OpenNMS Horizon web application, whereas the user within the group OpenNMS-Admins can configure OpenNMS Horizon and have additionally administrative permissions.

Securing the connection with LDAPS and using self-signed certificates in Java is another topic and not covered here.

Preparing Microsoft ADS

Step 1: Create a bind user which is used to execute the LDAP search queries

Step 2: Create the Groups in Active Directory and assign the Users into the groups

Step 3: Test the connection with ldapsearch and the bind user from your OpenNMS Horizon server

ldapsearch -x \
  -D 'cn=OpenNMS Bind User,cn=Users,dc=labmonkeys,dc=local' -W \
  -b 'cn=Users,dc=labmonkeys,dc=local' -h

:information_source: The openldap-client package provides the ldapsearch binary.

Configure OpenNMS Horizon

Step 1: Enable external authentication in Spring security context

vi ${OPENNMS_HOME}/jetty-webapps/opennms/WEB-INF/applicationContext-spring-security.xml

Uncomment the following line:

<authentication-provider ref="externalAuthenticationProvider" />

Step 2: Enable the external Active Directory Authentication security context

cd ${OPENNMS_HOME}/jetty-webapps/opennms/WEB-INF/spring-security.d/
cp activeDirectory.xml.disabled activeDirectory.xml

Step 3: Configure LDAP server for authentication

<beans:bean id="contextSource" class="">
  <beans:property name="urls">
      <!-- List one or more of your Active Directory domain controllers here -->
  <!-- An optional base DN. Every user and group below is relative to this. -->
  <beans:property name="base" value="dc=labmonkeys,dc=local" />
  <beans:property name="authenticationSource" ref="authenticationSource" />

Step 4: Configure bind user to search for LDAP objects

 <beans:bean id="authenticationSource" class="org.springframework.ldap.authentication.DefaultValuesAuthenticationSourceDecorator">
  <beans:property name="target" ref="springSecurityAuthenticationSource"/>
  <!-- Identify an unprivileged user for initial binding to the directory -->
  <!-- In some cases, expressing the user as an LDAP DN is the right way -->
  <beans:property name="defaultUser" value="CN=OpenNMS Bind User,CN=Users,DC=labmonkeys,DC=local"/>
  <!-- In other cases, it's necessary to express it in user@domain format -->
  <!-- <beans:property name="defaultUser" value=""/> -->
  <!-- Specify the unprivileged bind user's password here -->
  <beans:property name="defaultPassword" value="MyPass123!"/>

Step 5: Set the user search to CN=Users

<beans:bean id="userSearch" class="">
  <beans:constructor-arg index="0" value="CN=Users" />

  <!-- More complex filters are possible depending on the layout of your directory -->
  <beans:constructor-arg index="1" value="(sAMAccountName={0})" />
  <beans:constructor-arg index="2" ref="contextSource" />
  <beans:property name="searchSubtree" value="true" />

Step 6: Set the search path for groups for role mapping

  <beans:bean id="userGroupLdapAuthoritiesPopulator" class="">
    <beans:constructor-arg ref="contextSource"/>
    <!-- Common LDAP container for the user and admin groups listed below -->
    <beans:constructor-arg value="cn=Users" />

Step 7: Restart OpenNMS Horizon and login with your Active Directory User

For troubleshooting you can watch the Jetty web log.

tail -f ${OPENNMS_HOME}/logs/jetty-server.log | grep "LDAP:"