Active Directory example with referral enabled
This example covers the scenario where more than one Active Directory domain works together and the follow parameter is needed.
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 dc=company,dc=com by default.
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 for 30-45 minutes by OpenKM to prevent overloading the LDAP server. You can clear the cache from Administration > Tools > Cache stats. In the second step, configure login. This configuration always works in real time.
Step 1 - configuration parameters
We suggest login to OpenKM using the admin URL (for example http://localhost:8080/openkm/admin/index) because in the next steps it will be necessary to restart the OpenKM service and you do not want to lose administrative access.
The first action should be to modify principal.adapter parameter value and restart the OpenKM service. Because the session ID is kept in the browser, you should not lose the login after the service is restarted and you can continue working in the administration. After this change, the users and roles lists will be empty in the administration. Until the next parameters are successfully configured, these lists will remain empty.
Go to Administration > Configuration parameters:
Field / Property | Type | Description |
---|---|---|
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 |
|
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 domain servers working together (balanced).
- Users defined in any Active Directory node will be able to log in because it has DC=company,DC=com defined as the base filter.
- Any user authenticated in Active Directory can log in because there is no filtering clause.
- Groups read by OpenKM can be defined in any Active Directory node because it has DC=company,DC=com defined as the 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 updating the openkm.properties file, you must restart the OpenKM service for the changes to take effect.
Another option to configure login
In some cases, you might be interested in setting the configuration in the openkm.xml file; 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>