Active Directory example with referral enabled

This example covers the scenario where more than one Active Directory domains work together and it's needed the follow parameter.

LDAP Structure

dc=com
    dc=company
        ou=OPENKM
            cn=ROLE_ADMIN
                member=okmAdmin
                member=user1
                member=user2
            cn=ROLE_USER
                member=user3
                member=user4
            cn=ROLE_XXXX
            cn=ROLE_YYYY
                ...
        ou=organization1
            sAMAccountName=okmAdmin
                memberOf=CN=ROLE_ADMIN,OU=OPENKM,DC=company,DC=com
                mail=okmAdmin@mail.com
                cn=OpenKM Administrator
            sAMAccountName=user1
                memberOf=CN=ROLE_ADMIN,OU=OPENKM,DC=company,DC=com
                mail=user1@mail.com
                cn=User Name 1
            sAMAccountName=user2
                memberOf=CN=ROLE_ADMIN,OU=OPENKM,DC=company,DC=com
                mail=user2@mail.com
                cn=User Name 3
        ou=organization2
            sAMAccountName=user3
                memberOf=CN=ROLE_USER,OU=OPENKM,DC=company,DC=com
                mail=user3@mail.com
                cn=User Name 3
            sAMAccountName=user4
                memberOf=CN=ROLE_USER,OU=OPENKM,DC=company,DC=com
                mail=user4@mail.com
                cn=User Name 4

Valid groups:

  • cn=ROLE_ADMIN,ou=OPENKM,dc=company,dc=com
  • cn=ROLE_USER,ou=OPENKM,dc=company,dc=com
  • cn=ROLE_XXXX,ou=OPENKM,dc=company,dc=com
  • cn=ROLE_YYYY,ou=OPENKM,dc=company,dc=com

Valid users:

  • cn=user1,ou=organization1,dc=company,dc=com
  • cn=user2,ou=organization1,dc=company,dc=com
  • cn=user3,ou=organization2,dc=company,dc=com
  • cn=user4,ou=organization2,dc=company,dc=com

Any distinguished name includes by default dc=company,dc=com

The OpenKM integration with LDAP has two steps. In the first step, configure OpenKM to retrieve the list of users and roles from the LDAP. This list is cached during 30-45 minutes by OpenKM to prevent overloading the LDAP server. You can clean the cache from Administration > Tools > Cache stats. In the second step configure login, this configuration works always in real time.

Step 1 - configuration parameters

We suggest login in OpenKM with the admin URL ( for example http://localhost:8080/openkm/admin/index ) because in the next steps will be necessary to restart OpenKM service and you do not want to lose administration access.

The first action should be to modify principal.adapter parameter value and restart OpenKM service. Because session ID is kept in the browser you should not lose the login after the service restarted and can continue working in the administration. After this change, the users and roles list will be empty from the administration. Until success configuring the next parameters these lists will be empty.

Go to Administration > Configuration parameters:

Field / PropertyTypeDescription
principal.adapter String

com.openkm.plugin.principal.LdapPrincipalAdapter

system.login.lowercase String

true

principal.ldap.server String

ldap://192.168.xxx.xxx:389

principal.ldap.security.principal String

CN=Administrator,OU=OPENKM,DC=company,DC=com

principal.ldap.security.credentials String

password

principal.ldap.referral String

follow

principal.ldap.users.from.roles    Boolean

false

principal.ldap.user.attribute String

sAMAccountName

principal.ldap.user.search.base

List

DC=company,DC=com

principal.ldap.user.search.filter

String

(objectclass=user)

principal.ldap.username.attribute

String

cn

principal.ldap.username.search.base

String

DC=company,DC=com

principal.ldap.username.search.filter

String

(&(objectClass=person)(sAMAccountName={0}))

principal.ldap.mail.attribute String

mail

principal.ldap.mail.search.base String

DC=company,DC=com

principal.ldap.mail.search.filter String

(&(objectClass=person)(sAMAccountName={0}))

principal.ldap.role.attribute

String

cn

principal.ldap.role.search.base

List

DC=company,DC=com

principal.ldap.role.search.filter

String

(objectclass=group)

principal.ldap.roles.by.user.attribute

String

memberOf

principal.ldap.roles.by.user.search.base

String

DC=company,DC=com

principal.ldap.roles.by.user.search.filter

String

(&(objectClass=person)(sAMAccountName={0}))

principal.ldap.users.by.role.attribute

String

member

principal.ldap.users.by.role.search.base

String

DC=company,DC=com

principal.ldap.users.by.role.search.filter

String

(&(objectClass=group)(CN={0}))

Step 2 - configure login

  • Parameter follow indicates several domains servers working together ( balanced ).
  • Users defined in any Active Directory node will be able to login, because it has defined DC=company,DC=com as base filter.
  • Any user authenticated in Active Directory can login because has not any filtering clausule.
  • Groups read by OpenKM can be defined in any Active Directory node, because it has defined DC=company,DC=com as base filter.

Apply changes in the openkm.properties file.

The parameter "okm.authentication.database" is used to disable database login.

The parameter "okm.authentication.ldap" is used to enable ldap login.

#Authentication
okm.authentication.database=false
okm.authentication.ldap=true

#LDAP
ldap.server=ldap://192.168.0.13
ldap.manager.distinguished.name=CN=Administrator,CN=Users,DC=openkm,DC=local
ldap.manager.password=*secret*
ldap.base=DC=openkm,DC=local
ldap.role.attribute=cn
ldap.user.search.filter=sAMAccountName={0}
ldap.role.search.filter=member={0}

After the update of the openkm.properties file must restart the openkm service to take effect.

Another option to configure login

In some cases might be interested to set configuration in file openkm.xml please refer to Configuring openkm.xml documentation section for more information.

<security:authentication-manager alias="authenticationManager">
    <security:authentication-provider ref="ldapAuthProvider" />
  </security:authentication-manager>
 
  <beans:bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
    <beans:constructor-arg value="ldap://192.168.xxx.xxx:389"/>
    <beans:property name="userDn" value="CN=Administrator,OU=OPENKM,DC=company,DC=com"/>
    <beans:property name="password" value="****"/>
    <beans:property name="baseEnvironmentProperties">
      <beans:map>
        <beans:entry>
          <beans:key>
            <beans:value>java.naming.referral</beans:value>
          </beans:key>
          <beans:value>follow</beans:value>
        </beans:entry>
      </beans:map>
    </beans:property>
  </beans:bean>
 
  <beans:bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
    <beans:constructor-arg>
      <beans:bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
        <beans:constructor-arg ref="contextSource"/>
        <beans:property name="userSearch" ref="userSearch"/>
      </beans:bean>
    </beans:constructor-arg>
    <beans:constructor-arg name="authoritiesPopulator" ref="defaultLdapAuthoritiesPopulator"/>
  </beans:bean>
 
  <beans:bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
    <beans:constructor-arg index="0" value="DC=company,DC=com" />
    <beans:constructor-arg index="1" value="sAMAccountName={0}" />
    <beans:constructor-arg index="2" ref="contextSource" />
    <beans:property name="searchSubtree" value="true" />
  </beans:bean>
  
  <beans:bean id="defaultLdapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
		<beans:constructor-arg ref="contextSource"/>
		<beans:constructor-arg value="DC=openkm,DC=local"/>
		<beans:property name="groupSearchFilter" value="member={0}"/>
		<beans:property name="groupRoleAttribute" value="cn"/>
		<beans:property name="searchSubtree" value="true" />
		<beans:property name="convertToUpperCase" value="false" />
		<beans:property name="rolePrefix" value="" />
	</beans:bean>
	
	<!--Needed for remember-me services -->
	<beans:bean id="userDetailService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">
		<beans:constructor-arg ref="userSearch"/>
		<beans:constructor-arg ref="defaultLdapAuthoritiesPopulator"/>
	</beans:bean>