Active Directory example with remember-me services

In this example, we'll see an Active Directory connection that allows to connect any Active Directory authenticated user member of ROLE_USER or ROLE_ADMIN as the same time as using remeber me services.

Available since OpenKM 6.4.25 version

LDAP structure 

dc=com
    dc=company
        ou=OPENKM
            cn=ROLE_ADMIN
                member=okmAdmin
                member=user1
            cn=ROLE_USER
                member=user3
            cn=ROLE_XXXX
                member=user2
            cn=ROLE_YYYY
                member=user4
                ...
        ou=organization1
            sAMAccountName=okmAdmin
                memberOf=CN=ROLE_ADMIN,OU=OPENKM,DC=company,DC=com
                userPrincipalName=okmAdmin@mail.com
                cn=OpenKM Administrator
            sAMAccountName=user1
                memberOf=CN=ROLE_ADMIN,OU=OPENKM,DC=company,DC=com
                userPrincipalName=user1@mail.com
                cn=User Name 1
            sAMAccountName=user2
                memberOf=CN=ROLE_XXXX,OU=OPENKM,DC=company,DC=com
                userPrincipalName=user2@mail.com
                cn=User Name 3
        ou=organization2
            sAMAccountName=user3
                memberOf=CN=ROLE_USER,OU=OPENKM,DC=company,DC=com
                userPrincipalName=user3@mail.com
                cn=User Name 3
            sAMAccountName=user4
                memberOf=CN=ROLE_YYYY,OU=OPENKM,DC=company,DC=com
                userPrincipalName=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

Invalid users:

  • 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 except users which are not member of ROLE_ADMIN or ROLE_USER

OpenKM.xml

  • Users created in any Active Directory node members of ROLE_ADMIN or ROLE_USER will be able to login, because it has defined DC=company,DC=com as base filter, and as user account filter.
  • Groups read by OpenKM can be created in any Active Directory node, because it has defined DC=company,DC=com as base filter.
  • DefaultLdapAuthorities populator has been extracted to an independent bean in order to be able to use it in userDetailService Bean as well as ldapAuthProvider bean.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:security="http://www.springframework.org/schema/security"
             xmlns:task="http://www.springframework.org/schema/task"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             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
                                 http://www.springframework.org/schema/task
                                 http://www.springframework.org/schema/task/spring-task.xsd">
 
<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"/>
  <beans:property name="userDn" value="CN=connect,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="defaultLdapAuthoritiesPopulator" class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">    
	<beans:constructor-arg ref="contextSource"/> 
	<beans:constructor-arg value="DC=company,DC=com"/>    
	<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>
 
 <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="(&amp;(sAMAccountName={0})(|(memberOf=CN=ROLE_ADMIN,OU=OpenKM,DC=company,DC=com)(memberOf=CN=ROLE_USER,OU=OpenKM,DC=company,DC=com)))" />
   <beans:constructor-arg index="2" ref="contextSource" />
   <beans:property name="searchSubtree" value="true" />
 </beans:bean> 
 
 <beans:bean id="userDetailService" class="org.springframework.security.ldap.userdetails.LdapUserDetailsService">     
		<beans:constructor-arg ref="userSearch"/>     
		<beans:constructor-arg ref="databaseAuthoritiesPopulator"/> 
 </beans:bean>
 
</beans:beans>

Configuration parameters

  • User members of ROLE_ADMIN or ROLE_USER can be created in any active directory node, because it has defined DC=company,DC=com as base filter, principal.ldap.user.search.base=DC=company,DC=com and user search filter as principal.ldap.user.search.filter=(&(objectclass=user)(|(memberOf=CN=ROLE_ADMIN,OU=OpenKM,DC=company,DC=com).
  • Groups can be created in any active directory node, because is has DC=company,DC=com as base filter, principal.ldap.role.search.base=DC=company,DC=com.
  • All Active Directory groups will be listed, because it has not applied any filter restriction principal.ldap.role.search.filter=(objectclass=group).
  • Mail attribute used in this case is userPrincipalName ( the most usual ldap attribute to get mail is mail ) principal.ldap.mail.attribute=userPrincipalName.

Go to Administration > Configuration parameters:

Field / PropertyTypeDescription
principal.adapter String

com.openkm.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)(|(memberOf=CN=ROLE_ADMIN,OU=OpenKM,DC=company,DC=com)(memberOf=CN=ROLE_USER,OU=OpenKM,DC=company,DC=com)))

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

userPrincipalName

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

OU=OpenKM,DC=company,DC=com

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

String

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