]> git.argeo.org Git - lgpl/argeo-commons.git/blob - ArgeoSecurityDaoLdap.java
171252848f08dabbb9ab38298a5ddf8c29d0e35e
[lgpl/argeo-commons.git] / ArgeoSecurityDaoLdap.java
1 package org.argeo.security.ldap;
2
3 import static org.argeo.security.core.ArgeoUserDetails.createSimpleArgeoUser;
4
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import javax.naming.Name;
9 import javax.naming.NamingException;
10 import javax.naming.directory.DirContext;
11
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;
37
38 public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
39 // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
40
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_";
51
52 private final BaseLdapPathContextSource contextSource;
53 private final LdapTemplate ldapTemplate;
54
55 private LdapUsernameToDnMapper usernameMapper = null;
56
57 private UserDetailsContextMapper userDetailsMapper;
58 private LdapUserDetailsService ldapUserDetailsService;
59 private List<UserNatureMapper> userNatureMappers;
60
61 public void afterPropertiesSet() throws Exception {
62 if (usernameMapper == null)
63 usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
64 usernameAttributeName);
65
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;
72 }
73
74 if (userDetailsMapper == null) {
75 ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper();
76 audm.setUserNatureMappers(userNatureMappers);
77 userDetailsMapper = audm;
78 }
79
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;
88 }
89
90 if (ldapUserDetailsService == null) {
91 FilterBasedLdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch(
92 userBase, "(" + usernameAttributeName + "={0})",
93 contextSource);
94 ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch,
95 authoritiesPopulator);
96 ldapUserDetailsService.setUserDetailsMapper(userDetailsMapper);
97 }
98 }
99
100 public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) {
101 this.contextSource = contextSource;
102 ldapTemplate = new LdapTemplate(this.contextSource);
103 }
104
105 public void create(ArgeoUser user) {
106 userDetailsManager.createUser(new ArgeoUserDetails(user));
107 }
108
109 public ArgeoUser getUser(String uname) {
110 SimpleArgeoUser user = createSimpleArgeoUser(getDetails(uname));
111 user.setPassword(null);
112 return user;
113 }
114
115 public ArgeoUser getUserWithPassword(String uname) {
116 return createSimpleArgeoUser(getDetails(uname));
117 }
118
119 public ArgeoUser getCurrentUser() {
120 Authentication authentication = SecurityContextHolder.getContext()
121 .getAuthentication();
122 ArgeoUser argeoUser = ArgeoUserDetails.asArgeoUser(authentication);
123 if (argeoUser == null)
124 return null;
125 if (argeoUser.getRoles().contains(defaultRole))
126 argeoUser.getRoles().remove(defaultRole);
127 return argeoUser;
128 }
129
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);
137 }
138 });
139
140 List<ArgeoUser> lst = new ArrayList<ArgeoUser>();
141 for (String username : usernames) {
142 lst.add(createSimpleArgeoUser(getDetails(username)));
143 }
144 return lst;
145 }
146
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);
155 return roleName;
156 }
157 });
158 }
159
160 public void update(ArgeoUser user) {
161 userDetailsManager.updateUser(new ArgeoUserDetails(user));
162 }
163
164 public void delete(String username) {
165 userDetailsManager.deleteUser(username);
166 }
167
168 public Boolean userExists(String username) {
169 return userDetailsManager.userExists(username);
170 }
171
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);
180 }
181 });
182
183 Name groupDn = buildGroupDn(group);
184 DirContextAdapter context = new DirContextAdapter();
185 context.setAttributeValues("objectClass", groupClasses);
186 context.setAttributeValue("cn", group);
187
188 // Add superuser because cannot create empty group
189 context.setAttributeValue(groupMemberAttributeName, superuserDn
190 .toString());
191
192 ldapTemplate.bind(groupDn, context, null);
193 }
194
195 public void deleteRole(String role) {
196 String group = convertRoleToGroup(role);
197 Name dn = buildGroupDn(group);
198 ldapTemplate.unbind(dn);
199 }
200
201 protected String convertRoleToGroup(String role) {
202 String group = role;
203 if (group.startsWith(rolePrefix)) {
204 group = group.substring(rolePrefix.length());
205 group = group.toLowerCase();
206 }
207 return group;
208 }
209
210 public String convertGroupToRole(String groupName) {
211 groupName = groupName.toUpperCase();
212
213 return rolePrefix + groupName;
214 }
215
216 protected Name buildGroupDn(String name) {
217 return new DistinguishedName(groupRoleAttributeName + "=" + name + ","
218 + groupBase);
219 }
220
221 public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
222 this.userDetailsManager = userDetailsManager;
223 }
224
225 public void setUserBase(String userBase) {
226 this.userBase = userBase;
227 }
228
229 public void setUsernameAttributeName(String usernameAttribute) {
230 this.usernameAttributeName = usernameAttribute;
231 }
232
233 public void setAuthoritiesPopulator(
234 LdapAuthoritiesPopulator authoritiesPopulator) {
235 this.authoritiesPopulator = authoritiesPopulator;
236 }
237
238 protected UserDetails getDetails(String username) {
239 return userDetailsManager.loadUserByUsername(username);
240 }
241
242 public void setGroupBase(String groupBase) {
243 this.groupBase = groupBase;
244 }
245
246 public void setGroupRoleAttributeName(String groupRoleAttributeName) {
247 this.groupRoleAttributeName = groupRoleAttributeName;
248 }
249
250 public void setGroupMemberAttributeName(String groupMemberAttributeName) {
251 this.groupMemberAttributeName = groupMemberAttributeName;
252 }
253
254 public void setDefaultRole(String defaultRole) {
255 this.defaultRole = defaultRole;
256 }
257
258 public void setRolePrefix(String rolePrefix) {
259 this.rolePrefix = rolePrefix;
260 }
261
262 public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
263 this.usernameMapper = usernameMapper;
264 }
265
266 public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
267 this.userDetailsMapper = userDetailsMapper;
268 }
269
270 public LdapAuthoritiesPopulator getAuthoritiesPopulator() {
271 return authoritiesPopulator;
272 }
273
274 public UserDetailsContextMapper getUserDetailsMapper() {
275 return userDetailsMapper;
276 }
277
278 public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
279 this.userNatureMappers = userNatureMappers;
280 }
281
282 public String getDefaultRole() {
283 return defaultRole;
284 }
285
286 public void setGroupClasses(String[] groupClasses) {
287 this.groupClasses = groupClasses;
288 }
289
290 public UserDetailsService getUserDetailsService() {
291 return ldapUserDetailsService;
292 }
293
294 }