1 package org
.argeo
.security
.ldap
;
3 import static org
.argeo
.security
.core
.ArgeoUserDetails
.createSimpleArgeoUser
;
5 import java
.util
.ArrayList
;
8 import javax
.naming
.Name
;
9 import javax
.naming
.NamingException
;
10 import javax
.naming
.directory
.DirContext
;
12 import org
.argeo
.security
.ArgeoSecurityDao
;
13 import org
.argeo
.security
.ArgeoUser
;
14 import org
.argeo
.security
.SimpleArgeoUser
;
15 import org
.argeo
.security
.core
.ArgeoUserDetails
;
16 import org
.springframework
.beans
.factory
.InitializingBean
;
17 import org
.springframework
.ldap
.core
.ContextExecutor
;
18 import org
.springframework
.ldap
.core
.ContextMapper
;
19 import org
.springframework
.ldap
.core
.DirContextAdapter
;
20 import org
.springframework
.ldap
.core
.DistinguishedName
;
21 import org
.springframework
.ldap
.core
.LdapTemplate
;
22 import org
.springframework
.ldap
.core
.support
.BaseLdapPathContextSource
;
23 import org
.springframework
.security
.Authentication
;
24 import org
.springframework
.security
.context
.SecurityContextHolder
;
25 import org
.springframework
.security
.ldap
.DefaultLdapUsernameToDnMapper
;
26 import org
.springframework
.security
.ldap
.LdapAuthoritiesPopulator
;
27 import org
.springframework
.security
.ldap
.LdapUsernameToDnMapper
;
28 import org
.springframework
.security
.ldap
.LdapUtils
;
29 import org
.springframework
.security
.ldap
.populator
.DefaultLdapAuthoritiesPopulator
;
30 import org
.springframework
.security
.ldap
.search
.FilterBasedLdapUserSearch
;
31 import org
.springframework
.security
.userdetails
.UserDetails
;
32 import org
.springframework
.security
.userdetails
.UserDetailsManager
;
33 import org
.springframework
.security
.userdetails
.UserDetailsService
;
34 import org
.springframework
.security
.userdetails
.ldap
.LdapUserDetailsManager
;
35 import org
.springframework
.security
.userdetails
.ldap
.LdapUserDetailsService
;
36 import org
.springframework
.security
.userdetails
.ldap
.UserDetailsContextMapper
;
38 public class ArgeoSecurityDaoLdap
implements ArgeoSecurityDao
, InitializingBean
{
39 // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
41 private UserDetailsManager userDetailsManager
;
42 private LdapAuthoritiesPopulator authoritiesPopulator
;
43 private String userBase
= "ou=People";
44 private String usernameAttributeName
= "uid";
45 private String groupBase
= "ou=Roles";
46 private String
[] groupClasses
= { "top", "groupOfNames" };
47 private String groupRoleAttributeName
= "cn";
48 private String groupMemberAttributeName
= "member";
49 private String defaultRole
= "ROLE_USER";
50 private String rolePrefix
= "ROLE_";
52 private final BaseLdapPathContextSource contextSource
;
53 private final LdapTemplate ldapTemplate
;
55 private LdapUsernameToDnMapper usernameMapper
= null;
57 private UserDetailsContextMapper userDetailsMapper
;
58 private LdapUserDetailsService ldapUserDetailsService
;
59 private List
<UserNatureMapper
> userNatureMappers
;
61 public void afterPropertiesSet() throws Exception
{
62 if (usernameMapper
== null)
63 usernameMapper
= new DefaultLdapUsernameToDnMapper(userBase
,
64 usernameAttributeName
);
66 if (authoritiesPopulator
== null) {
67 DefaultLdapAuthoritiesPopulator ap
= new DefaultLdapAuthoritiesPopulator(
68 ldapTemplate
.getContextSource(), groupBase
);
69 ap
.setDefaultRole(defaultRole
);
70 ap
.setGroupSearchFilter(groupMemberAttributeName
+ "={0}");
71 authoritiesPopulator
= ap
;
74 if (userDetailsMapper
== null) {
75 ArgeoUserDetailsContextMapper audm
= new ArgeoUserDetailsContextMapper();
76 audm
.setUserNatureMappers(userNatureMappers
);
77 userDetailsMapper
= audm
;
80 if (userDetailsManager
== null) {
81 LdapUserDetailsManager ludm
= new LdapUserDetailsManager(
82 ldapTemplate
.getContextSource());
83 ludm
.setGroupSearchBase(groupBase
);
84 ludm
.setUserDetailsMapper(userDetailsMapper
);
85 ludm
.setUsernameMapper(usernameMapper
);
86 ludm
.setGroupMemberAttributeName(groupMemberAttributeName
);
87 userDetailsManager
= ludm
;
90 if (ldapUserDetailsService
== null) {
91 FilterBasedLdapUserSearch ldapUserSearch
= new FilterBasedLdapUserSearch(
92 userBase
, "(" + usernameAttributeName
+ "={0})",
94 ldapUserDetailsService
= new LdapUserDetailsService(ldapUserSearch
,
95 authoritiesPopulator
);
96 ldapUserDetailsService
.setUserDetailsMapper(userDetailsMapper
);
100 public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource
) {
101 this.contextSource
= contextSource
;
102 ldapTemplate
= new LdapTemplate(this.contextSource
);
105 public void create(ArgeoUser user
) {
106 userDetailsManager
.createUser(new ArgeoUserDetails(user
));
109 public ArgeoUser
getUser(String uname
) {
110 SimpleArgeoUser user
= createSimpleArgeoUser(getDetails(uname
));
111 user
.setPassword(null);
115 public ArgeoUser
getUserWithPassword(String uname
) {
116 return createSimpleArgeoUser(getDetails(uname
));
119 public ArgeoUser
getCurrentUser() {
120 Authentication authentication
= SecurityContextHolder
.getContext()
121 .getAuthentication();
122 ArgeoUser argeoUser
= ArgeoUserDetails
.asArgeoUser(authentication
);
123 if (argeoUser
== null)
125 if (argeoUser
.getRoles().contains(defaultRole
))
126 argeoUser
.getRoles().remove(defaultRole
);
130 @SuppressWarnings("unchecked")
131 public List
<ArgeoUser
> listUsers() {
132 List
<String
> usernames
= (List
<String
>) ldapTemplate
.listBindings(
133 new DistinguishedName(userBase
), new ContextMapper() {
134 public Object
mapFromContext(Object ctxArg
) {
135 DirContextAdapter ctx
= (DirContextAdapter
) ctxArg
;
136 return ctx
.getStringAttribute(usernameAttributeName
);
140 List
<ArgeoUser
> lst
= new ArrayList
<ArgeoUser
>();
141 for (String username
: usernames
) {
142 lst
.add(createSimpleArgeoUser(getDetails(username
)));
147 @SuppressWarnings("unchecked")
148 public List
<String
> listEditableRoles() {
149 return (List
<String
>) ldapTemplate
.listBindings(groupBase
,
150 new ContextMapper() {
151 public Object
mapFromContext(Object ctxArg
) {
152 String groupName
= ((DirContextAdapter
) ctxArg
)
153 .getStringAttribute(groupRoleAttributeName
);
154 String roleName
= convertGroupToRole(groupName
);
160 public void update(ArgeoUser user
) {
161 userDetailsManager
.updateUser(new ArgeoUserDetails(user
));
164 public void delete(String username
) {
165 userDetailsManager
.deleteUser(username
);
168 public Boolean
userExists(String username
) {
169 return userDetailsManager
.userExists(username
);
172 public void createRole(String role
, final String superuserName
) {
173 String group
= convertRoleToGroup(role
);
174 DistinguishedName superuserDn
= (DistinguishedName
) ldapTemplate
175 .executeReadWrite(new ContextExecutor() {
176 public Object
executeWithContext(DirContext ctx
)
177 throws NamingException
{
178 return LdapUtils
.getFullDn(usernameMapper
179 .buildDn(superuserName
), ctx
);
183 Name groupDn
= buildGroupDn(group
);
184 DirContextAdapter context
= new DirContextAdapter();
185 context
.setAttributeValues("objectClass", groupClasses
);
186 context
.setAttributeValue("cn", group
);
188 // Add superuser because cannot create empty group
189 context
.setAttributeValue(groupMemberAttributeName
, superuserDn
192 ldapTemplate
.bind(groupDn
, context
, null);
195 public void deleteRole(String role
) {
196 String group
= convertRoleToGroup(role
);
197 Name dn
= buildGroupDn(group
);
198 ldapTemplate
.unbind(dn
);
201 protected String
convertRoleToGroup(String role
) {
203 if (group
.startsWith(rolePrefix
)) {
204 group
= group
.substring(rolePrefix
.length());
205 group
= group
.toLowerCase();
210 public String
convertGroupToRole(String groupName
) {
211 groupName
= groupName
.toUpperCase();
213 return rolePrefix
+ groupName
;
216 protected Name
buildGroupDn(String name
) {
217 return new DistinguishedName(groupRoleAttributeName
+ "=" + name
+ ","
221 public void setUserDetailsManager(UserDetailsManager userDetailsManager
) {
222 this.userDetailsManager
= userDetailsManager
;
225 public void setUserBase(String userBase
) {
226 this.userBase
= userBase
;
229 public void setUsernameAttributeName(String usernameAttribute
) {
230 this.usernameAttributeName
= usernameAttribute
;
233 public void setAuthoritiesPopulator(
234 LdapAuthoritiesPopulator authoritiesPopulator
) {
235 this.authoritiesPopulator
= authoritiesPopulator
;
238 protected UserDetails
getDetails(String username
) {
239 return userDetailsManager
.loadUserByUsername(username
);
242 public void setGroupBase(String groupBase
) {
243 this.groupBase
= groupBase
;
246 public void setGroupRoleAttributeName(String groupRoleAttributeName
) {
247 this.groupRoleAttributeName
= groupRoleAttributeName
;
250 public void setGroupMemberAttributeName(String groupMemberAttributeName
) {
251 this.groupMemberAttributeName
= groupMemberAttributeName
;
254 public void setDefaultRole(String defaultRole
) {
255 this.defaultRole
= defaultRole
;
258 public void setRolePrefix(String rolePrefix
) {
259 this.rolePrefix
= rolePrefix
;
262 public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper
) {
263 this.usernameMapper
= usernameMapper
;
266 public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper
) {
267 this.userDetailsMapper
= userDetailsMapper
;
270 public LdapAuthoritiesPopulator
getAuthoritiesPopulator() {
271 return authoritiesPopulator
;
274 public UserDetailsContextMapper
getUserDetailsMapper() {
275 return userDetailsMapper
;
278 public void setUserNatureMappers(List
<UserNatureMapper
> userNatureMappers
) {
279 this.userNatureMappers
= userNatureMappers
;
282 public String
getDefaultRole() {
286 public void setGroupClasses(String
[] groupClasses
) {
287 this.groupClasses
= groupClasses
;
290 public UserDetailsService
getUserDetailsService() {
291 return ldapUserDetailsService
;