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