Connect Deploy to your LDAP or Active Directory

By default, Deploy authenticates users and retrieves authorization information from its repository. You can also configure Deploy to use an LDAP repository to authenticate users and to retrieve role (group) membership. In this scenario, the LDAP users and groups are used as principals in Deploy that can be mapped to Deploy roles. Role membership and rights assigned to roles are always stored in the Deploy repository.

Deploy treats the LDAP repository as read-only. Deploy will use the information from the LDAP repository, but can not make changes to that information.

To configure Deploy to use an LDAP repository, you must change the security configuration file (deployit-security.xml).

The following is a step-by-step procedure describing how to connect Deploy to your LDAP or Active Directory infrastructure.

Step 1 Get your LDAP credentials

Check with your system administrator for your LDAP credentials and the search filters that should be used to find users and group members in LDAP. The administrator should also provide the distinguished names (DNs) to use as starting points for the search.

Note: You can use an LDAP browser such as JXplorer to verify that the credentials are correct. You can also use an LDAP browser to identify a user that has permission to log in to Deploy and a group that should be a principal in Deploy. You can then use this information to determine the filter and DN.

You need the following information to update the XL_DEPLOY_SERVER_HOME/conf/deployit-security.xml file:

Placeholder Description Example
LDAP_SERVER_URL LDAP URL to connect to ldap://localhost:389/
MANAGER_DN Principal to perform the initial bind to the LDAP server cn=admin,dc=example,dc=com
MANAGER_PASSWORD Credentials to perform the initial bind to the LDAP server. Encrypt your password by adding a property and binding it to any secret. For more information, see manage encrypted passwords. secret
USER_SEARCH_BASE LDAP DN to use as the basis for searching for users dc=example,dc=com
USER_SEARCH_FILTER LDAP filter to determine the LDAP DN for the user who is logging in; {0} will be replaced with the username (&(uid={0})(objectClass=inetOrgPerson))
GROUP_SEARCH_BASE LDAP filter to use as a basis for searching for groups ou=groups,dc=example,dc=com
GROUP_SEARCH_FILTER LDAP filter to determine group memberships of the user; {0} will be replaced with the DN of the user (memberUid={0})

Note: You can use the GROUP_SEARCH_FILTER to improve performance for users with larger number of authorities such as: (&(memberUid={0})(|(cn=Deploy_App*)(cn=Role_Deploy_*))) or (&(memberUid={0})(|(Name=Deploy_App_Admin)(Name=Role_Deploy_User))). You can replace the cn attribute name with the one defined in your repository. Alternatively, you can replace the cn attribute value with different wildcard expressions or exact matches.

Escaping special characters

Because deployit-security.xml is an XML file, you must escape certain characters in the values that will replace placeholders.

Character Escape with
& &
" "
' '
< &lt;
> &gt;

Step 2 Add the LDAP server definition

Add the following code to the deployit-security.xml file. Replace LDAP_SERVER_URL, MANAGER_DN, MANAGER_PASSWORD with your credentials.

<bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="LDAP_SERVER_URL" />
    <property name="userDn" value="MANAGER_DN" />
    <property name="password" value="MANAGER_PASSWORD" />
    <property name="baseEnvironmentProperties">
      <map>
        <entry key="java.naming.referral">
          <value>ignore</value>
        </entry>
      </map>
    </property>
</bean>

Important: Credentials are case-sensitive.

Restart Deploy and ensure that the server starts without any exceptions.

Step 3 Add LDAP user authentication

Add the following code to deployit-security.xml. Replace USER_SEARCH_BASE, USER_SEARCH_FILTER, GROUP_SEARCH_BASE, and GROUP_SEARCH_BASE with your credentials.

<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
  <constructor-arg index="0" value="USER_SEARCH_BASE" />
  <constructor-arg index="1" value="USER_SEARCH_FILTER" />
  <constructor-arg index="2" ref="ldapServer" />
</bean>
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
  <constructor-arg ref="ldapServer" />
  <constructor-arg value="GROUP_SEARCH_BASE" />
  <property name="groupSearchFilter" value="GROUP_SEARCH_FILTER" />
  <property name="rolePrefix" value="" />
  <property name="searchSubtree" value="true" />
  <property name="convertToUpperCase" value="false" />
</bean>
<bean id="ldapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
  <constructor-arg>
    <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
      <constructor-arg ref="ldapServer" />
        <property name="userSearch" ref="userSearch">
      </property>
    </bean>
  </constructor-arg>
  <constructor-arg ref="authoritiesPopulator" />
</bean>  

Important: Credentials are case-sensitive.

Also, locate the following section and add ldapProvider as an authentication provider:

<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider ref="rememberMeAuthenticationProvider" />
  <security:authentication-provider ref="XlAuthenticationProvider" />
  <security:authentication-provider ref="ldapProvider" />
</security:authentication-manager>

Note: ldapProvider should come after XlAuthenticationProvider. This ensures that, if there is a problem with LDAP, you can still log in to Deploy as a local user.

Restart Deploy and ensure that the server starts without any exceptions.

Step 4 Add the user in Deploy

Add the user as a principal in the Deploy GUI and assign the principal permission to log in.

Log out, then verify that you can log in with the user.

Step 5 Add the group in Deploy

Add the group as a principal in the Deploy GUI and assign the principal permission to log in.

Log out, then verify that you can log in with the group.

Sample deployit-security.xml file

This sample deployit-security.xml file shows the required LDAP configuration in context.

Note: Other parts of your deployit-security.xml file may differ from this example, depending on the version of Deploy that you are using.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:security="http://www.springframework.org/schema/security" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd ">
<bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
 <constructor-arg value="ldap://localhost:389/" />
 <property name="userDn" value="cn=admin,dc=example,dc=com" />
 <property name="password" value="secret" />
 <property name="baseEnvironmentProperties">
   <map>
	 <entry key="java.naming.referral">
	   <value>ignore</value>
	 </entry>
   </map>
 </property>
</bean>

<bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
   <constructor-arg index="0" value="dc=springframework,dc=org" />
   <constructor-arg index="1" value="(&amp;(uid={0})(objectClass=inetOrgPerson))" />
   <constructor-arg index="2" ref="ldapServer" />
</bean>
<bean id="authoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
   <constructor-arg ref="ldapServer" />
   <constructor-arg value="ou=groups,dc=springframework,dc=org" />
   <property name="groupSearchFilter" value="(member={0})" />
   <property name="rolePrefix" value="" />
   <property name="searchSubtree" value="true" />
   <property name="convertToUpperCase" value="false" />
</bean>

<bean id="ldapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
 <constructor-arg>
      <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
          <constructor-arg ref="ldapServer" />
          <property name="userSearch" ref="userSearch"/>
      </bean>
 </constructor-arg>
 <constructor-arg ref="authoritiesPopulator"/>
</bean>

<bean id="userDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
  <constructor-arg index="0" ref="userSearch"/>
  <constructor-arg index="1" ref="authoritiesPopulator"/>
</bean>

<bean id="rememberMeAuthenticationProvider" class="com.xebialabs.deployit.security.authentication.RememberMeAuthenticationProvider"/>
<bean id="XlAuthenticationProvider" class="com.xebialabs.deployit.security.authentication.XlAuthenticationProvider"/>

<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider ref="rememberMeAuthenticationProvider" />
  <security:authentication-provider ref="XlAuthenticationProvider" />
  <security:authentication-provider ref="ldapProvider" />
</security:authentication-manager>

</beans>

Assign a default role to all authenticated users

If your LDAP is not set up with a group to which all Deploy users are assigned, or if you want to use such a group in the default XlAuthenticationProvider, you can configure this in the deployit-security.xml file.

The following example shows how to set up a group called everyone, which is assigned to each user who is authenticated. You could then link this group to a Deploy role and, for example, assign it the login permission.

<beans>
    ...

    <bean id="ldapProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <constructor-arg>
            ...
        </constructor-arg>

        <property name="authoritiesMapper" ref="additionalAuthoritiesMapper" />
    </bean>

    <bean id="userDetailsService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
        <constructor-arg index="0" ref="userSearch"/>
        <constructor-arg index="1" ref="authoritiesPopulator"/>
    </bean>

    <bean id="XlAuthenticationProvider" class="com.xebialabs.deployit.security.authentication.XlAuthenticationProvider">
        <property name="authoritiesMapper" ref="additionalAuthoritiesMapper" />
    </bean>

    <bean id="additionalAuthoritiesMapper" class="com.xebialabs.deployit.security.AdditionalAuthoritiesMapper">
        <property name="additionalAuthorities">
            <list>
                <value>everyone</value>
            </list>
        </property>
    </bean>

</beans>