XL Release has a role-based security system with two types of users:

  • Internal users that are managed by XL Release
  • External users that are maintained in an LDAP repository such as Active Directory

This topic describes how to configure XL Release to use an LDAP repository to authenticate users and retrieve role (group) membership. In XL Release, LDAP users and groups become principals that you can assign to roles. Global permissions are assigned at the role level.

While role memberships and permissions assigned to roles are stored in XL Release’s JCR repository, XL Release treats the LDAP repository as read-only. This means that XL Release will use information from the LDAP repository, but it cannot make changes to that information.

Note: XL Release cookies store security information that is provided by the Spring Security framework. XL Release does not store any additional information in cookies.

Sample XL Release security file

To configure XL Release to use an LDAP repository, modify the xl-release-security.xml security configuration file. This is an example of a xl-release-security.xml file that uses LDAP. Values that you must provide are highlighted.

<?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"
    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_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>

    <bean id="ldapProvider" class="com.xebialabs.xlrelease.security.authentication.LdapAuthenticationProvider">
        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <constructor-arg ref="ldapServer" />
                <property name="userSearch">
                    <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>
                </property>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean 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>
        </constructor-arg>
    </bean>

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

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

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

</beans>

Note: This sample may differ from your xl-release-security.xml file, depending on your version of XL Release and any other customizations that have been done. It is recommended that you only add the highlighted items, instead of copying the entire sample.

Required LDAP information

Update xl-release-security.xml with information about your LDAP setup:

Placeholder Description Example
LDAP_SERVER_URL LDAP URL to connect to ldap://localhost:1389/
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; see Configure custom passwords for information about encrypting this password secret
USER_SEARCH_FILTER LDAP filter to determine the LDAP dn for the user who is logging in; {0} will be replaced with the user name (&amp;(uid={0})(objectClass=inetOrgPerson))
USER_SEARCH_BASE LDAP filter to use as a basis for searching for users dc=example,dc=com
GROUP_SEARCH_FILTER LDAP filter to determine the group memberships of the user; {0} will be replaced with the dn of the user (memberUid={0})
GROUP_SEARCH_BASE LDAP filter to use as a basis for searching for groups ou=groups,dc=example,dc=com

After you enter your values, restart the XL Release server. Add the user and group as principals in the XL Release interface and assign them permission to log in.

Tip: Below we provide a concrete example how a possible LDAP configuration could look like. Tip: Use an LDAP browser such as JXplorer to verify that the credentials are correct.

Escaping special characters

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

Character Escape with
& &amp;
" &quot;
' &apos;
< &lt;
> &gt;

Example: Allow users of a certain group to login only

For convenience we provide a filled in security.xml to show you how this could work.

Like the template description above, the interesting bits have been marked.

Do note that this is based on an openldap implementation. Filter queries may differ based on your ldap setup and vendor.

<?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"
       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="rememberMeAuthenticationProvider" class="com.xebialabs.deployit.security.authentication.RememberMeAuthenticationProvider"/>
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="rememberMeAuthenticationProvider" />
        <!--     <security:authentication-provider ref="xlAuthenticationProvider"/>-->
        <security:authentication-provider ref="ldapProvider" />
    </security:authentication-manager>
    <bean id="ldapServer" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldap://192.168.0.1:389" />
        <property name="userDn" value="cn=admin,dc=test,dc=com" />
        <property name="password" value="myPassword" />
        <property name="baseEnvironmentProperties">
            <map>
                <entry key="java.naming.referral" value="ignore"/>
            </map>
        </property>
    </bean>
    <bean id="ldapUserSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg index="0" value="dc=test,dc=com"/>
        <!-- Use this LDAP filter query to allow only users from a specific Organisational Unit -->
        <constructor-arg index="1" value="(&(objectclass=posixAccount)(entryDN=cn={0},cn=MY_AD_GROUP,ou=Security,ou=Groups,ou=France,ou=Regions,dc=test,dc=com)"/>
        <constructor-arg index="2" ref="ldapServer"/>
    </bean>
    <bean id="ldapProvider" class="com.xebialabs.xlrelease.security.authentication.LdapAuthenticationProvider">
        <constructor-arg>
            <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
                <constructor-arg ref="ldapServer" />
                <property name="userSearch" ref="ldapUserSearch"/>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
                <constructor-arg ref="ldapServer" />
                <!-- Do note that this filter is used for authorities, not logging in -->
                <constructor-arg value="dc=test,dc=com" />
                <property name="groupSearchFilter" value="(&(objectclass=group)(member={0}))" />
                <property name="rolePrefix" value="" />
                <property name="searchSubtree" value="true" />
                <property name="convertToUpperCase" value="false" />
            </bean>
        </constructor-arg>
    </bean>
</beans>

Assign a default role to all authenticated users

If you have an LDAP setup in which there is not a group that contains all XL Release users, and you want to use such a group in the default XlAuthenticationProvider (JcrAuthenticationProvider in XL Release 4.7.x and earlier), you can configure this in the xl-release-security.xml file.

This example creates a group called everyone that is assigned to each user who is authenticated (the group name can be anything you want). You can then link this group to a XL Release role and assign a global permission to it.

<beans>
    ...

    <bean id="ldapProvider" class="com.xebialabs.xlrelease.security.authentication.LdapAuthenticationProvider">
        <constructor-arg>
            ...
        </constructor-arg>

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

    <bean id="jcrAuthenticationProvider" 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>

Example of team security setup

You can setup an LDAP/Active Directory group called devs to be used by the members of a team in XL Release. Assign this group to a role in XL Release called Developers. At folder or release level, you can add permissions for a team called Dev Team that contains the XL Release role Developers. This role contains the created LDAP/Active Directory group called devs.

When you log in as a user to the devs group using LDAP/Active Directory, you automatically have the permissions for the Developers role at folder or release level.