From: Mathieu Baudier Date: Fri, 18 Mar 2011 15:42:23 +0000 (+0000) Subject: Clean up LDAP dao X-Git-Tag: argeo-commons-2.1.30~1343 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=b614eb03ce70d86fd6d02fc443ce11e7125e467d;p=lgpl%2Fargeo-commons.git Clean up LDAP dao git-svn-id: https://svn.argeo.org/commons/trunk@4321 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap-osgi.xml b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap-osgi.xml index fcfa5fed1..b09aabfe4 100644 --- a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap-osgi.xml +++ b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap-osgi.xml @@ -24,7 +24,7 @@ context-class-loader="service-provider" /> - \ No newline at end of file diff --git a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap.xml b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap.xml index 02ee71b1d..7a2ae9d7f 100644 --- a/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap.xml +++ b/security/modules/org.argeo.security.dao.ldap/META-INF/spring/ldap.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd"> - + @@ -24,33 +24,84 @@ + - - - - + + - + - + + + + + - - - - + + - + + + + - uid={0},ou=People + top + ${argeo.ldap.groupClass} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/security/modules/org.argeo.security.dao.ldap/ldap.properties b/security/modules/org.argeo.security.dao.ldap/ldap.properties index 1b24ee3d1..66eb37b43 100644 --- a/security/modules/org.argeo.security.dao.ldap/ldap.properties +++ b/security/modules/org.argeo.security.dao.ldap/ldap.properties @@ -1,6 +1,16 @@ +argeo.security.defaultRole=ROLE_USER +argeo.security.rolePrefix=ROLE_ + argeo.ldap.rootdn=dc=demo,dc=argeo,dc=org argeo.ldap.protocol=ldap argeo.ldap.host=localhost argeo.ldap.port=10389 argeo.ldap.manager.userdn=uid=admin,ou=system argeo.ldap.manager.password=secret + +argeo.ldap.userBase=ou=People +argeo.ldap.usernameAttribute=uid +argeo.ldap.groupClass=groupOfNames +argeo.ldap.groupBase=ou=Roles +argeo.ldap.groupRoleAttribute=cn +argeo.ldap.groupMemberAttribute=member diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/AbstractUserNature.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/AbstractUserNature.java index 2a3e2579d..bbb5eb804 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/AbstractUserNature.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/AbstractUserNature.java @@ -18,6 +18,7 @@ package org.argeo.security; /** A set of specific data attached to a user. */ +@Deprecated public abstract class AbstractUserNature implements UserNature { private static final long serialVersionUID = 1169323440459736478L; diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java index 30f52ed3b..465c2fab9 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/ArgeoUser.java @@ -23,6 +23,7 @@ import java.util.Map; public interface ArgeoUser { public String getUsername(); + @Deprecated public Map getUserNatures(); /** Implementation should refuse to add new user natures via this method. */ diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserService.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserService.java index 0cdae48fc..a82bc9bac 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserService.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/CurrentUserService.java @@ -7,6 +7,7 @@ public interface CurrentUserService { public void updateCurrentUserPassword(String oldPassword, String newPassword); + @Deprecated public void updateCurrentUserNatures(Map userNatures); } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java index c021f8e44..94c7f9389 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/SimpleArgeoUser.java @@ -53,10 +53,12 @@ public class SimpleArgeoUser implements ArgeoUser, Serializable, return userNatures; } + @Deprecated public void updateUserNatures(Map userNaturesData) { updateUserNaturesWithCheck(userNatures, userNaturesData); } + @Deprecated public static void updateUserNaturesWithCheck( Map userNatures, Map userNaturesData) { @@ -109,6 +111,7 @@ public class SimpleArgeoUser implements ArgeoUser, Serializable, this.username = username; } + @Deprecated public void setUserNatures(Map userNatures) { this.userNatures = userNatures; } diff --git a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java index 8931be2b0..cf0fa4819 100644 --- a/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java +++ b/security/runtime/org.argeo.security.core/src/main/java/org/argeo/security/UserNature.java @@ -22,6 +22,7 @@ import java.io.Serializable; * A set of specific data attached to a user. TODO: is this interface really * useful? */ +@Deprecated public interface UserNature extends Serializable { @Deprecated /** @deprecated will be removed soon*/ diff --git a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java index 0a10cce3f..4c6e62b98 100644 --- a/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java +++ b/security/runtime/org.argeo.security.ldap/src/main/java/org/argeo/security/ldap/ArgeoSecurityDaoLdap.java @@ -36,7 +36,6 @@ import org.argeo.security.CurrentUserDao; import org.argeo.security.SimpleArgeoUser; import org.argeo.security.UserAdminDao; import org.argeo.security.core.ArgeoUserDetails; -import org.springframework.beans.factory.InitializingBean; import org.springframework.ldap.core.ContextExecutor; import org.springframework.ldap.core.ContextMapper; import org.springframework.ldap.core.DirContextAdapter; @@ -44,95 +43,58 @@ import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.support.BaseLdapPathContextSource; import org.springframework.security.context.SecurityContextHolder; -import org.springframework.security.ldap.DefaultLdapUsernameToDnMapper; -import org.springframework.security.ldap.LdapAuthoritiesPopulator; import org.springframework.security.ldap.LdapUsernameToDnMapper; import org.springframework.security.ldap.LdapUtils; -import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator; -import org.springframework.security.ldap.search.FilterBasedLdapUserSearch; import org.springframework.security.providers.UsernamePasswordAuthenticationToken; import org.springframework.security.providers.encoding.PasswordEncoder; import org.springframework.security.userdetails.UserDetails; import org.springframework.security.userdetails.UserDetailsManager; -import org.springframework.security.userdetails.UserDetailsService; -import org.springframework.security.userdetails.ldap.LdapUserDetailsManager; -import org.springframework.security.userdetails.ldap.LdapUserDetailsService; -import org.springframework.security.userdetails.ldap.UserDetailsContextMapper; -public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, - InitializingBean { - // private final static Log log = LogFactory.getLog(UserDaoLdap.class); +/** + * Wraps a Spring LDAP user details manager, providing additional methods to + * manage roles. + */ +public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao { + private String userBase; + private String usernameAttribute; + private String groupBase; + private String[] groupClasses; - private UserDetailsManager userDetailsManager; - private LdapAuthoritiesPopulator authoritiesPopulator; - private String userBase = "ou=People"; - private String usernameAttributeName = "uid"; - private String groupBase = "ou=Roles"; - private String[] groupClasses = { "top", "groupOfNames" }; - private String groupRoleAttributeName = "cn"; - private String groupMemberAttributeName = "member"; - private String defaultRole = "ROLE_USER"; - private String rolePrefix = "ROLE_"; - - private final BaseLdapPathContextSource contextSource; - private final LdapTemplate ldapTemplate; + private String groupRoleAttribute; + private String groupMemberAttribute; + private String defaultRole; + private String rolePrefix; - private LdapUsernameToDnMapper usernameMapper = null; + private final LdapTemplate ldapTemplate; + private final Random random; - private UserDetailsContextMapper userDetailsMapper; - private LdapUserDetailsService ldapUserDetailsService; - private List userNatureMappers; + private LdapUsernameToDnMapper usernameMapper; + private UserDetailsManager userDetailsManager; private PasswordEncoder passwordEncoder; - private Random random; + /** + * Standard constructor, using the LDAP context source shared with Spring + * Security components. + */ public ArgeoSecurityDaoLdap(BaseLdapPathContextSource contextSource) { - this.contextSource = contextSource; - ldapTemplate = new LdapTemplate(this.contextSource); - - try { - random = SecureRandom.getInstance("SHA1PRNG"); - } catch (NoSuchAlgorithmException e) { - random = new Random(System.currentTimeMillis()); - } + this(new LdapTemplate(contextSource), createRandom()); } - public void afterPropertiesSet() throws Exception { - if (usernameMapper == null) - usernameMapper = new DefaultLdapUsernameToDnMapper(userBase, - usernameAttributeName); - - if (authoritiesPopulator == null) { - DefaultLdapAuthoritiesPopulator ap = new DefaultLdapAuthoritiesPopulator( - ldapTemplate.getContextSource(), groupBase); - ap.setDefaultRole(defaultRole); - ap.setGroupSearchFilter(groupMemberAttributeName + "={0}"); - authoritiesPopulator = ap; - } - - if (userDetailsMapper == null) { - ArgeoUserDetailsContextMapper audm = new ArgeoUserDetailsContextMapper(); - audm.setUserNatureMappers(userNatureMappers); - userDetailsMapper = audm; - } - - if (userDetailsManager == null) { - LdapUserDetailsManager ludm = new LdapUserDetailsManager( - ldapTemplate.getContextSource()); - ludm.setGroupSearchBase(groupBase); - ludm.setUserDetailsMapper(userDetailsMapper); - ludm.setUsernameMapper(usernameMapper); - ludm.setGroupMemberAttributeName(groupMemberAttributeName); - userDetailsManager = ludm; - } + /** + * Advanced constructor allowing to reuse an LDAP template and to explicitly + * set the random used as seed for SSHA password generation. + */ + public ArgeoSecurityDaoLdap(LdapTemplate ldapTemplate, Random random) { + this.ldapTemplate = ldapTemplate; + this.random = random; + } - if (ldapUserDetailsService == null) { - FilterBasedLdapUserSearch ldapUserSearch = new FilterBasedLdapUserSearch( - userBase, "(" + usernameAttributeName + "={0})", - contextSource); - ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch, - authoritiesPopulator); - ldapUserDetailsService.setUserDetailsMapper(userDetailsMapper); + private static Random createRandom() { + try { + return SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + return new Random(System.currentTimeMillis()); } } @@ -159,22 +121,13 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, return createSimpleArgeoUser(getDetails(uname)); } - // public ArgeoUser getCurrentUser() { - // ArgeoUser argeoUser = ArgeoUserDetails.securityContextUser(); - // if (argeoUser == null) - // return null; - // if (argeoUser.getRoles().contains(defaultRole)) - // argeoUser.getRoles().remove(defaultRole); - // return argeoUser; - // } - @SuppressWarnings("unchecked") public synchronized Set listUsers() { List usernames = (List) ldapTemplate.listBindings( new DistinguishedName(userBase), new ContextMapper() { public Object mapFromContext(Object ctxArg) { DirContextAdapter ctx = (DirContextAdapter) ctxArg; - return ctx.getStringAttribute(usernameAttributeName); + return ctx.getStringAttribute(usernameAttribute); } }); @@ -191,7 +144,7 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, ldapTemplate.listBindings(groupBase, new ContextMapper() { public Object mapFromContext(Object ctxArg) { String groupName = ((DirContextAdapter) ctxArg) - .getStringAttribute(groupRoleAttributeName); + .getStringAttribute(groupRoleAttribute); String roleName = convertGroupToRole(groupName); return roleName; } @@ -205,12 +158,11 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, public Object mapFromContext(Object ctxArg) { DirContextAdapter ctx = (DirContextAdapter) ctxArg; String[] userDns = ctx - .getStringAttributes(groupMemberAttributeName); + .getStringAttributes(groupMemberAttribute); TreeSet set = new TreeSet(); for (String userDn : userDns) { DistinguishedName dn = new DistinguishedName(userDn); - String username = dn - .getValue(usernameAttributeName); + String username = dn.getValue(usernameAttribute); set.add(createSimpleArgeoUser(getDetails(username))); } return Collections.unmodifiableSortedSet(set); @@ -284,11 +236,8 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, DirContextAdapter context = new DirContextAdapter(); context.setAttributeValues("objectClass", groupClasses); context.setAttributeValue("cn", group); - // Add superuser because cannot create empty group - context.setAttributeValue(groupMemberAttributeName, - superuserDn.toString()); - + context.setAttributeValue(groupMemberAttribute, superuserDn.toString()); ldapTemplate.bind(groupDn, context, null); } @@ -298,6 +247,7 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, ldapTemplate.unbind(dn); } + /** Maps a role (ROLE_XXX) to the related LDAP group (xxx) */ protected String convertRoleToGroup(String role) { String group = role; if (group.startsWith(rolePrefix)) { @@ -307,14 +257,15 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, return group; } - public String convertGroupToRole(String groupName) { + /** Maps anLDAP group (xxx) to the related role (ROLE_XXX) */ + protected String convertGroupToRole(String groupName) { groupName = groupName.toUpperCase(); return rolePrefix + groupName; } protected Name buildGroupDn(String name) { - return new DistinguishedName(groupRoleAttributeName + "=" + name + "," + return new DistinguishedName(groupRoleAttribute + "=" + name + "," + groupBase); } @@ -326,13 +277,8 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, this.userBase = userBase; } - public void setUsernameAttributeName(String usernameAttribute) { - this.usernameAttributeName = usernameAttribute; - } - - public void setAuthoritiesPopulator( - LdapAuthoritiesPopulator authoritiesPopulator) { - this.authoritiesPopulator = authoritiesPopulator; + public void setUsernameAttribute(String usernameAttribute) { + this.usernameAttribute = usernameAttribute; } protected UserDetails getDetails(String username) { @@ -343,12 +289,12 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, this.groupBase = groupBase; } - public void setGroupRoleAttributeName(String groupRoleAttributeName) { - this.groupRoleAttributeName = groupRoleAttributeName; + public void setGroupRoleAttribute(String groupRoleAttributeName) { + this.groupRoleAttribute = groupRoleAttributeName; } - public void setGroupMemberAttributeName(String groupMemberAttributeName) { - this.groupMemberAttributeName = groupMemberAttributeName; + public void setGroupMemberAttribute(String groupMemberAttributeName) { + this.groupMemberAttribute = groupMemberAttributeName; } public void setDefaultRole(String defaultRole) { @@ -363,22 +309,6 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, this.usernameMapper = usernameMapper; } - public void setUserDetailsMapper(UserDetailsContextMapper userDetailsMapper) { - this.userDetailsMapper = userDetailsMapper; - } - - public LdapAuthoritiesPopulator getAuthoritiesPopulator() { - return authoritiesPopulator; - } - - public UserDetailsContextMapper getUserDetailsMapper() { - return userDetailsMapper; - } - - public void setUserNatureMappers(List userNatureMappers) { - this.userNatureMappers = userNatureMappers; - } - public String getDefaultRole() { return defaultRole; } @@ -387,10 +317,6 @@ public class ArgeoSecurityDaoLdap implements CurrentUserDao, UserAdminDao, this.groupClasses = groupClasses; } - public UserDetailsService getUserDetailsService() { - return ldapUserDetailsService; - } - public void setPasswordEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; }