Bundle-SymbolicName: org.argeo.security.manager.ldap
Bundle-Version: 0.1.1.SNAPSHOT
-Import-Package: org.springframework.security.ldap,
+Import-Package: org.argeo.security.dao,
+ org.argeo.security.ldap,
+ org.springframework.ldap.core.support,
+ org.springframework.security,
+ org.springframework.security.ldap,
+ org.springframework.security.ldap.populator,
org.springframework.security.providers,
org.springframework.security.providers.ldap,
org.springframework.security.providers.ldap.authenticator,
- org.springframework.security.ldap.populator,
- org.springframework.security.userdetails.ldap,
- org.springframework.security,
- org.springframework.ldap.core.support
+ org.springframework.security.userdetails,
+ org.springframework.security.userdetails.ldap
--- /dev/null
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:security="http://www.springframework.org/schema/security"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ 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">
+
+
+ <bean id="userDao" class="org.argeo.security.ldap.UserDaoLdap">
+ <constructor-arg ref="contextSource" />
+ <property name="userDetailsManager" ref="userDetailsManager" />
+ <property name="authoritiesPopulator" ref="authoritiesPopulator" />
+ </bean>
+
+</beans>
</property>
</bean>
</constructor-arg>
- <constructor-arg>
+ <constructor-arg ref="authoritiesPopulator" />
+ <property name="userDetailsContextMapper" ref="userDetailsMapper" />
+ </bean>
+
+ <bean id="authoritiesPopulator"
+ class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
+ <constructor-arg ref="contextSource" />
+ <constructor-arg value="ou=groups" />
+ <!-- <property name="defaultRole" value="ROLE_USER" /> -->
+ <property name="groupSearchFilter" value="uniqueMember={0}" />
+ </bean>
+
+ <bean id="userDetailsManager"
+ class="org.springframework.security.userdetails.ldap.LdapUserDetailsManager">
+ <constructor-arg ref="contextSource" />
+ <property name="userDetailsMapper" ref="userDetailsMapper" />
+ <property name="groupSearchBase" value="ou=groups" />
+ <property name="usernameMapper">
<bean
- class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
- <constructor-arg ref="contextSource" />
- <constructor-arg value="ou=groups" />
- <!-- <property name="defaultRole" value="ROLE_USER" /> -->
- <property name="groupSearchFilter" value="uniqueMember={0}" />
+ class="org.springframework.security.ldap.DefaultLdapUsernameToDnMapper">
+ <constructor-arg value="ou=users" />
+ <constructor-arg value="uid" />
</bean>
- </constructor-arg>
+ </property>
</bean>
+ <bean id="userDetailsMapper" class="org.argeo.security.ldap.ArgeoUserDetailsContextMapper">
+ <property name="userNatureMappers">
+ <list>
+ <bean class="org.argeo.security.ldap.SimpleUserNatureMapper" />
+ <bean class="org.argeo.security.ldap.CoworkerUserNatureMapper" />
+ </list>
+ </property>
+ </bean>
</beans>
\r
<service ref="_authenticationManager"\r
interface="org.springframework.security.AuthenticationManager" />\r
- <!-- <service ref="authenticationProvider"\r
- interface="org.springframework.security.providers.AuthenticationProvider" /> -->\r
+\r
+ <service ref="userDao" interface="org.argeo.security.dao.UserDao" />\r
</beans:beans>
\ No newline at end of file
-Web-ContextPath: org.argeo.security.webapp
Bundle-SymbolicName: org.argeo.security.webapp
Bundle-Version: 0.1.1.SNAPSHOT
Import-Package: javax.servlet,
org.springframework.web.context,
org.springframework.web.context.support,
org.springframework.web.filter,
- org.springframework.web.servlet
+ org.springframework.web.servlet,
+ org.argeo.security.dao
+Web-ContextPath: org.argeo.security.webapp
\r
<reference id="_authenticationManager"\r
interface="org.springframework.security.AuthenticationManager" />\r
+\r
+ <reference id="userDao" interface="org.argeo.security.dao.UserDao" />\r
+\r
</beans:beans>
\ No newline at end of file
<context:component-scan base-package="org.argeo.security.mvc" />
- <bean id="controller" class="org.argeo.security.mvc.UsersRolesController"></bean>
+ <bean id="controller" class="org.argeo.security.mvc.UsersRolesController">
+ <property name="userDao" ref="userDao" />
+ </bean>
<bean id="viewResolver" class="org.argeo.server.json.mvc.JsonViewResolver">
</bean>
package org.argeo.security;
+import java.io.Serializable;
import java.util.UUID;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
//@JsonAutoDetect(value = { JsonMethod.GETTER, JsonMethod.SETTER })
-public class UserNature {
- private final static Log log = LogFactory.getLog(UserNature.class);
+public class UserNature implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ // private final static Log log = LogFactory.getLog(UserNature.class);
private String uuid = UUID.randomUUID().toString();
private String type;
this.type = type;
}
-// @JsonAnySetter
-// public void anySetter(String key, Object obj) {
-// if (obj != null)
-// log.info("anySetter: " + key + "=" + obj + " (" + obj.getClass()
-// + "), natureType=" + type);
-// }
+ // @JsonAnySetter
+ // public void anySetter(String key, Object obj) {
+ // if (obj != null)
+ // log.info("anySetter: " + key + "=" + obj + " (" + obj.getClass()
+ // + "), natureType=" + type);
+ // }
}
import org.argeo.security.UserNature;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
+import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
getAuthorities(), new ArrayList<String>()));
}
+ public ArgeoUserDetails(ArgeoUser argeoUser) {
+ // TODO: password
+ this(argeoUser.getUsername(), argeoUser.getUserNatures(), null,
+ rolesToAuthorities(argeoUser.getRoles()));
+ }
+
public List<UserNature> getUserNatures() {
return userNatures;
}
return roles;
}
+ protected static GrantedAuthority[] rolesToAuthorities(List<String> roles) {
+ GrantedAuthority[] arr = new GrantedAuthority[roles.size()];
+ for (int i = 0; i < roles.size(); i++) {
+ arr[i] = new GrantedAuthorityImpl(roles.get(i));
+ }
+ return arr;
+ }
+
public static BasicArgeoUser createBasicArgeoUser(UserDetails userDetails) {
BasicArgeoUser argeoUser = new BasicArgeoUser();
argeoUser.setUsername(userDetails.getUsername());
return argeoUser;
}
- public static BasicArgeoUser createBasicArgeoUser(
- Authentication authentication) {
- BasicArgeoUser argeoUser = new BasicArgeoUser();
- argeoUser.setUsername(authentication.getName());
- addAuthoritiesToRoles(authentication.getAuthorities(), argeoUser
- .getRoles());
- return argeoUser;
+ public static ArgeoUser asArgeoUser(Authentication authentication) {
+ if (authentication.getPrincipal() instanceof ArgeoUser) {
+ return (ArgeoUser) authentication.getPrincipal();
+ } else {
+ BasicArgeoUser argeoUser = new BasicArgeoUser();
+ argeoUser.setUsername(authentication.getName());
+ addAuthoritiesToRoles(authentication.getAuthorities(), argeoUser
+ .getRoles());
+ return argeoUser;
+ }
}
}
--- /dev/null
+package org.argeo.security.dao;
+
+import java.util.List;
+
+import org.argeo.security.ArgeoUser;
+
+public interface RoleDao {
+ public List<String> listRoles();
+
+ public void create(String role);
+
+ public List<String> listUserRoles(ArgeoUser user);
+
+}
--- /dev/null
+package org.argeo.security.dao;
+
+import java.util.List;
+
+import org.argeo.security.ArgeoUser;
+
+public interface UserDao {
+ public List<ArgeoUser> listUsers();
+
+ public void create(ArgeoUser user);
+
+ public void update(ArgeoUser user);
+
+ public void delete(String username);
+
+ public void updatePassword(String oldPassword, String newPassword);
+
+ public Boolean userExists(String username);
+
+ public ArgeoUser getUser(String uname);
+
+}
import java.util.Collections;
import java.util.List;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.argeo.security.ArgeoUser;
import org.argeo.security.UserNature;
import org.argeo.security.core.ArgeoUserDetails;
import org.springframework.security.userdetails.ldap.UserDetailsContextMapper;
public class ArgeoUserDetailsContextMapper implements UserDetailsContextMapper {
- private List<UserNatureMapper> userInfoMappers = new ArrayList<UserNatureMapper>();
+ private final static Log log = LogFactory
+ .getLog(ArgeoUserDetailsContextMapper.class);
+
+ private List<UserNatureMapper> userNatureMappers = new ArrayList<UserNatureMapper>();
public UserDetails mapUserFromContext(DirContextOperations ctx,
String username, GrantedAuthority[] authorities) {
String password = new String(arr);
List<UserNature> userInfos = new ArrayList<UserNature>();
- for (UserNatureMapper userInfoMapper : userInfoMappers) {
- userInfos.add(userInfoMapper.mapUserInfoFromContext(ctx));
+ for (UserNatureMapper userInfoMapper : userNatureMappers) {
+ UserNature userNature = userInfoMapper.mapUserInfoFromContext(ctx);
+ if (log.isDebugEnabled())
+ log.debug("Add user nature " + userNature);
+ userInfos.add(userNature);
}
return new ArgeoUserDetails(username, Collections
if (user instanceof ArgeoUser) {
ArgeoUser argeoUser = (ArgeoUser) user;
for (UserNature userInfo : argeoUser.getUserNatures()) {
- for (UserNatureMapper userInfoMapper : userInfoMappers) {
+ for (UserNatureMapper userInfoMapper : userNatureMappers) {
if (userInfoMapper.supports(userInfo)) {
userInfoMapper.mapUserInfoToContext(userInfo, ctx);
break;// use the first mapper found an no others
}
}
- public void setUserInfoMappers(List<UserNatureMapper> userInfoMappers) {
- this.userInfoMappers = userInfoMappers;
+ public void setUserNatureMappers(List<UserNatureMapper> userNatureMappers) {
+ this.userNatureMappers = userNatureMappers;
}
}
basicUserInfo.setMobile(ctx.getStringAttribute("mobile"));
basicUserInfo.setTelephoneNumber(ctx
.getStringAttribute("telephoneNumber"));
+ basicUserInfo.setUuid(ctx.getStringAttribute("employeeNumber"));
return basicUserInfo;
}
- public void mapUserInfoToContext(UserNature userInfoArg, DirContextAdapter ctx) {
+ public void mapUserInfoToContext(UserNature userInfoArg,
+ DirContextAdapter ctx) {
CoworkerNature userInfo = (CoworkerNature) userInfoArg;
+ ctx.setAttributeValue("employeeNumber", userInfo.getUuid());
if (userInfo.getDescription() != null) {
ctx.setAttributeValue("description", userInfo.getDescription());
}
basicUserInfo.setLastName(ctx.getStringAttribute("sn"));
basicUserInfo.setFirstName(ctx.getStringAttribute("givenName"));
basicUserInfo.setEmail(ctx.getStringAttribute("mail"));
+ basicUserInfo.setUuid(ctx.getStringAttribute("seeAlso"));
return basicUserInfo;
}
ctx.setAttributeValue("sn", userInfo.getLastName());
ctx.setAttributeValue("givenName", userInfo.getFirstName());
ctx.setAttributeValue("mail", userInfo.getEmail());
+ // TODO: find a cleaner way?
+ ctx.setAttributeValue("seeAlso", userInfo.getUuid());
}
public Boolean supports(UserNature userInfo) {
--- /dev/null
+package org.argeo.security.ldap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.naming.NamingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.security.ArgeoUser;
+import org.argeo.security.BasicArgeoUser;
+import org.argeo.security.core.ArgeoUserDetails;
+import org.argeo.security.dao.UserDao;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.ContextSource;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator;
+import org.springframework.security.userdetails.UserDetails;
+import org.springframework.security.userdetails.UserDetailsManager;
+
+public class UserDaoLdap implements UserDao {
+ private final static Log log = LogFactory.getLog(UserDaoLdap.class);
+
+ private UserDetailsManager userDetailsManager;
+ private DefaultLdapAuthoritiesPopulator authoritiesPopulator;
+ private String userBase = "ou=users";
+
+ private final LdapTemplate ldapTemplate;
+
+ public UserDaoLdap(ContextSource contextSource) {
+ ldapTemplate = new LdapTemplate(contextSource);
+ }
+
+ public void create(ArgeoUser user) {
+ userDetailsManager.createUser((UserDetails) user);
+ }
+
+ public ArgeoUser getUser(String uname) {
+ return (ArgeoUser) userDetailsManager.loadUserByUsername(uname);
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<ArgeoUser> listUsers() {
+ List<String> usernames = (List<String>) ldapTemplate.listBindings(
+ new DistinguishedName(userBase), new UserContextMapper());
+ List<ArgeoUser> lst = new ArrayList<ArgeoUser>();
+ for (String username : usernames) {
+ UserDetails userDetails = userDetailsManager
+ .loadUserByUsername(username);
+ lst.add((ArgeoUser) userDetails);
+ }
+ return lst;
+ }
+
+ public void update(ArgeoUser user) {
+ userDetailsManager.updateUser(new ArgeoUserDetails(user));
+ }
+
+ public void delete(String username) {
+ userDetailsManager.deleteUser(username);
+ }
+
+ public void updatePassword(String oldPassword, String newPassword) {
+ userDetailsManager.changePassword(oldPassword, newPassword);
+ }
+
+ public Boolean userExists(String username) {
+ return userDetailsManager.userExists(username);
+ }
+
+ public void setUserDetailsManager(UserDetailsManager userDetailsManager) {
+ this.userDetailsManager = userDetailsManager;
+ }
+
+ public void setAuthoritiesPopulator(
+ DefaultLdapAuthoritiesPopulator authoritiesPopulator) {
+ this.authoritiesPopulator = authoritiesPopulator;
+ }
+
+ public void setUserBase(String userBase) {
+ this.userBase = userBase;
+ }
+
+ class UserContextMapper implements ContextMapper {
+ public Object mapFromContext(Object ctxArg) {
+ DirContextAdapter ctx = (DirContextAdapter) ctxArg;
+ // BasicArgeoUser user = new BasicArgeoUser();
+ return ctx.getStringAttribute("uid");
+
+ // log.debug("dn# " + ctx.getDn());
+ // log.debug("NameInNamespace# " + ctx.getNameInNamespace());
+ // log.debug("toString# " + ctx.toString());
+
+ // Set<String> roles = authoritiesPopulator.getGroupMembershipRoles(
+ // ctx.composeName(user.getUsername(), userBase), user
+ // .getUsername());
+ // user.setRoles(new ArrayList<String>(roles));
+ // GrantedAuthority[] auths = authoritiesPopulator
+ // .getGrantedAuthorities(ldapTemplate.,
+ // user.getUsername());
+ // for (GrantedAuthority auth : auths) {
+ // user.getRoles().add(auth.getAuthority());
+ // }
+ // return user;
+ }
+ }
+
+}
</plugins>
</build>
<dependencies>
+ <!-- Argeo Server -->
+ <dependency>
+ <groupId>org.argeo.commons.server</groupId>
+ <artifactId>org.argeo.server.core</artifactId>
+ <version>0.1.1-SNAPSHOT</version>
+ </dependency>
+
<!-- Argeo Security -->
<dependency>
<groupId>org.argeo.commons.security</groupId>
package org.argeo.security.mvc;
+import java.util.List;
+
import org.argeo.security.ArgeoUser;
import org.argeo.security.core.ArgeoUserDetails;
+import org.argeo.security.dao.RoleDao;
+import org.argeo.security.dao.UserDao;
+import org.argeo.server.BooleanAnswer;
+import org.argeo.server.ServerAnswer;
import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class UsersRolesController {
+ private UserDao userDao;
+ private RoleDao roleDao;
@RequestMapping("/getCredentials.security")
@ModelAttribute("getCredentials")
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
- return ArgeoUserDetails.createBasicArgeoUser(authentication);
+ return ArgeoUserDetails.asArgeoUser(authentication);
+ }
+
+ @RequestMapping("/getUsersList.security")
+ @ModelAttribute("getUsersList")
+ public List<ArgeoUser> getUsersList() {
+ return userDao.listUsers();
+ }
+
+ @RequestMapping("/userExists.security")
+ @ModelAttribute("userExists")
+ public BooleanAnswer userExists(@RequestParam("username") String username) {
+ return new BooleanAnswer(userDao.userExists(username));
+ }
+
+ @RequestMapping("/deleteUser.security")
+ @ModelAttribute("deleteUser")
+ public ServerAnswer deleteUser(@RequestParam("username") String username) {
+ userDao.delete(username);
+ return ServerAnswer.ok(username + " deleted");
}
+
+ @RequestMapping("/getUserDetails.security")
+ @ModelAttribute("getUserDetails")
+ public ArgeoUser getUserDetails(@RequestParam("username") String username) {
+ return userDao.getUser(username);
+ }
+
+ public void setUserDao(UserDao userDao) {
+ this.userDao = userDao;
+ }
+
+ public void setRoleDao(RoleDao roleDao) {
+ this.roleDao = roleDao;
+ }
+
}
--- /dev/null
+package org.argeo.server;
+
+
+/** Answer to an execution of a remote service which performed changes. */
+public class BooleanAnswer {
+ private Boolean value = Boolean.TRUE;
+
+ /** Canonical constructor */
+ public BooleanAnswer(Boolean status) {
+ this.value = status;
+ }
+
+ /** Empty constructor */
+ public BooleanAnswer() {
+ }
+
+ public Boolean getValue() {
+ return value;
+ }
+
+}