Active Directory example with login based on filtering users by roles
In this example, we'll see an Active Directory connection that allows connecting any Active Directory authenticated user member of ROLE_USER or ROLE_ADMIN.
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 who are not a member of ROLE_ADMIN or ROLE_USER
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 common LDAP attribute to get mail is mail ) principal.ldap.mail.attribute=userPrincipalName.
Go to Administration > Configuration parameters:
Field / Property | Type | Description |
---|---|---|
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})) |
OpenKM.xml
- Users created in any Active Directory node members of ROLE_ADMIN or ROLE_USER will be able to log in because it has defined DC=company,DC=com as the base filter, and as user account filter.
- Groups read by OpenKM can be created in an Active Directory node, because it has defined DC=company,DC=com as the base filter.
<?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>
<beans:bean 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:constructor-arg>
</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})(|(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:beans>