]> git.argeo.org Git - lgpl/argeo-commons.git/blob - ArgeoSecurityDaoLdap.java
2fa2ce8b964fe8f1e091a384a621e8a6b888a624
[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.ContextSource;
20 import org.springframework.ldap.core.DirContextAdapter;
21 import org.springframework.ldap.core.DistinguishedName;
22 import org.springframework.ldap.core.LdapTemplate;
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.userdetails.UserDetails;
31 import org.springframework.security.userdetails.UserDetailsManager;
32 import org.springframework.security.userdetails.ldap.LdapUserDetailsManager;
33 import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
34
35 public class ArgeoSecurityDaoLdap implements ArgeoSecurityDao, InitializingBean {
36 // private final static Log log = LogFactory.getLog(UserDaoLdap.class);
37
38 private UserDetailsManager userDetailsManager;
39 private LdapAuthoritiesPopulator authoritiesPopulator;
40 private String userBase = "ou=users";
41 private String usernameAttributeName = "uid";
42 private String groupBase = "ou=groups";
43 private String groupRoleAttributeName = "cn";
44 private String groupMemberAttributeName = "uniquemember";
45 private String defaultRole = "ROLE_USER";
46 private String rolePrefix = "ROLE_";
47
48 private final LdapTemplate ldapTemplate;
49
50 private LdapUsernameToDnMapper usernameMapper = null;
51
52 private UserDetailsContextMapper userDetailsMapper;
53 private List<UserNatureMapper> userNatureMappers;
54
55 public void afterPropertiesSet() throws Exception {
56 if (usernameMapper == null)
57 usernameMapper = new DefaultLdapUsernameToDnMapper(userBase,
58 usernameAttributeName);
59
60 if (authoritiesPopulator == null) {
61 DefaultLdapAuthoritiesPopulator ap = new DefaultLdapAuthoritiesPopulator(
62 ldapTemplate.getContextSource(), groupBase);
63 ap.setDefaultRole(defaultRole);
64 ap.setGroupSearchFilter(groupMemberAttributeName + "={0}");
65 authoritiesPopulator = ap;
66 }
67
68 if (userDetailsMapper == null) {
69 ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper();
70 audm.setUserNatureMappers(userNatureMappers);
71 userDetailsMapper = audm;
72 }
73
74 if (userDetailsManager == null) {
75 LdapUserDetailsManager ludm = new LdapUserDetailsManager(
76 ldapTemplate.getContextSource());
77 ludm.setGroupSearchBase(groupBase);
78 ludm.setUserDetailsMapper(userDetailsMapper);
79 ludm.setUsernameMapper(usernameMapper);
80 ludm.setGroupMemberAttributeName(groupMemberAttributeName);
81 userDetailsManager = ludm;
82 }
83
84 }
85
86 public ArgeoSecurityDaoLdap(ContextSource contextSource) {
87 ldapTemplate = new LdapTemplate(contextSource);
88 }
89
90 public void create(ArgeoUser user) {
91 userDetailsManager.createUser(new ArgeoUserDetails(user));
92 }
93
94 public ArgeoUser getUser(String uname) {
95 SimpleArgeoUser user = createSimpleArgeoUser(getDetails(uname));
96 user.setPassword(null);
97 return user;
98 }
99
100 public ArgeoUser getUserWithPassword(String uname) {
101 return createSimpleArgeoUser(getDetails(uname));
102 }
103
104 public ArgeoUser getCurrentUser() {
105 Authentication authentication = SecurityContextHolder.getContext()
106 .getAuthentication();
107 ArgeoUser argeoUser = ArgeoUserDetails.asArgeoUser(authentication);
108 if (argeoUser == null)
109 return null;
110 if (argeoUser.getRoles().contains(defaultRole))
111 argeoUser.getRoles().remove(defaultRole);
112 return argeoUser;
113 }
114
115 @SuppressWarnings("unchecked")
116 public List<ArgeoUser> listUsers() {
117 List<String> usernames = (List<String>) ldapTemplate.listBindings(
118 new DistinguishedName(userBase), new ContextMapper() {
119 public Object mapFromContext(Object ctxArg) {
120 DirContextAdapter ctx = (DirContextAdapter) ctxArg;
121 return ctx.getStringAttribute(usernameAttributeName);
122 }
123 });
124
125 List<ArgeoUser> lst = new ArrayList<ArgeoUser>();
126 for (String username : usernames) {
127 lst.add(createSimpleArgeoUser(getDetails(username)));
128 }
129 return lst;
130 }
131
132 @SuppressWarnings("unchecked")
133 public List<String> listEditableRoles() {
134 return (List<String>) ldapTemplate.listBindings(groupBase,
135 new ContextMapper() {
136 public Object mapFromContext(Object ctxArg) {
137 String groupName = ((DirContextAdapter) ctxArg)
138 .getStringAttribute(groupRoleAttributeName);
139 String roleName = convertGroupToRole(groupName);
140 return roleName;
141 }
142 });
143 }
144
145 public void update(ArgeoUser user) {
146 userDetailsManager.updateUser(new ArgeoUserDetails(user));
147 }
148
149 public void delete(String username) {
150 userDetailsManager.deleteUser(username);
151 }
152
153 public void updatePassword(String oldPassword, String newPassword) {
154 userDetailsManager.changePassword(oldPassword, newPassword);
155 }
156
157 public Boolean userExists(String username) {
158 return userDetailsManager.userExists(username);
159 }
160
161 public void createRole(String role, final String superuserName) {
162 String group = convertRoleToGroup(role);
163 DistinguishedName superuserDn = (DistinguishedName) ldapTemplate
164 .executeReadWrite(new ContextExecutor() {
165 public Object executeWithContext(DirContext ctx)
166 throws NamingException {
167 return LdapUtils.getFullDn(usernameMapper
168 .buildDn(superuserName), ctx);
169 }
170 });
171
172 Name groupDn = buildGroupDn(group);
173 DirContextAdapter context = new DirContextAdapter();
174 context.setAttributeValues("objectClass", new String[] { "top",
175 "groupOfUniqueNames" });
176 context.setAttributeValue("cn", group);
177
178 // Add superuser because cannot create empty group
179 context.setAttributeValue("uniqueMember", superuserDn.toString());
180
181 ldapTemplate.bind(groupDn, context, null);
182 }
183
184 public void deleteRole(String role) {
185 String group = convertRoleToGroup(role);
186 Name dn = buildGroupDn(group);
187 ldapTemplate.unbind(dn);
188 }
189
190 protected String convertRoleToGroup(String role) {
191 String group = role;
192 if (group.startsWith(rolePrefix)) {
193 group = group.substring(rolePrefix.length());
194 group = group.toLowerCase();
195 }
196 return group;
197 }
198
199 public String convertGroupToRole(String groupName) {
200 groupName = groupName.toUpperCase();
201
202 return rolePrefix + groupName;
203 }
204
205 protected Name buildGroupDn(String name) {
206 return new DistinguishedName(groupRoleAttributeName + "=" + name + ","
207 + groupBase);
208 }
209
210 public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
211 this.userDetailsManager = userDetailsManager;
212 }
213
214 public void setUserBase(String userBase) {
215 this.userBase = userBase;
216 }
217
218 public void setUsernameAttributeName(String usernameAttribute) {
219 this.usernameAttributeName = usernameAttribute;
220 }
221
222 public void setAuthoritiesPopulator(
223 LdapAuthoritiesPopulator authoritiesPopulator) {
224 this.authoritiesPopulator = authoritiesPopulator;
225 }
226
227 protected UserDetails getDetails(String username) {
228 return userDetailsManager.loadUserByUsername(username);
229 }
230
231 public void setGroupBase(String groupBase) {
232 this.groupBase = groupBase;
233 }
234
235 public void setGroupRoleAttributeName(String groupRoleAttributeName) {
236 this.groupRoleAttributeName = groupRoleAttributeName;
237 }
238
239 public void setGroupMemberAttributeName(String groupMemberAttributeName) {
240 this.groupMemberAttributeName = groupMemberAttributeName;
241 }
242
243 public void setDefaultRole(String defaultRole) {
244 this.defaultRole = defaultRole;
245 }
246
247 public void setRolePrefix(String rolePrefix) {
248 this.rolePrefix = rolePrefix;
249 }
250
251 public void setUsernameMapper(LdapUsernameToDnMapper usernameMapper) {
252 this.usernameMapper = usernameMapper;
253 }
254
255 public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) {
256 this.userDetailsMapper = userDetailsMapper;
257 }
258
259 public LdapAuthoritiesPopulator getAuthoritiesPopulator() {
260 return authoritiesPopulator;
261 }
262
263 public UserDetailsContextMapper getUserDetailsMapper() {
264 return userDetailsMapper;
265 }
266
267 public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
268 this.userNatureMappers = userNatureMappers;
269 }
270
271 public String getDefaultRole() {
272 return defaultRole;
273 }
274 }