Experimental UserDetailsManager interface and some ldap implementation classes.

This commit is contained in:
Luke Taylor 2006-08-25 16:14:50 +00:00
parent 1b66467f70
commit 139d8c2f65
3 changed files with 267 additions and 0 deletions

View File

@ -0,0 +1,25 @@
package org.acegisecurity.userdetails;
/**
* An extension of the {@link UserDetailsService} which provides the ability
* to create new users and update existing ones.
*
* @author Luke
* @version $Id$
*/
public interface UserDetailsManager extends UserDetailsService {
/**
* Save details for the supplied user, or update
*
* @param user
*/
void createUser(UserDetails user);
void updateUser(UserDetails user);
void deleteUser(String username);
boolean userExists(String username);
}

View File

@ -0,0 +1,50 @@
package org.acegisecurity.userdetails.ldap;
/**
* @author Luke
* @version $Id$
*/
public class InetOrgPerson extends LdapUserDetailsImpl {
String sn;
String cn;
public String getSn() {
return sn;
}
public String getCn() {
return cn;
}
public static class Essence extends LdapUserDetailsImpl.Essence {
public Essence() {
}
public Essence(InetOrgPerson copyMe) {
super(copyMe);
}
LdapUserDetailsImpl createTarget() {
return new InetOrgPerson();
}
public void setSn(String sn) {
((InetOrgPerson)instance).sn = sn;
}
public void setCn(String cn) {
((InetOrgPerson)instance).cn = cn;
}
}
public static void main(String[] args) {
InetOrgPerson.Essence p = new InetOrgPerson.Essence();
p.setSn("Scobbie");
InetOrgPerson immutablePerson = (InetOrgPerson)p.createUserDetails();
System.out.println(immutablePerson.getSn());
}
}

View File

@ -0,0 +1,192 @@
package org.acegisecurity.userdetails.ldap;
import org.acegisecurity.userdetails.UserDetailsManager;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.ldap.ContextSourceInitialDirContextFactory;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.providers.ldap.authenticator.LdapShaPasswordEncoder;
import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;
import org.springframework.beans.BeanWrapperImpl;
import net.sf.ldaptemplate.ContextSource;
import net.sf.ldaptemplate.LdapTemplate;
import net.sf.ldaptemplate.EntryNotFoundException;
import net.sf.ldaptemplate.ContextMapper;
import net.sf.ldaptemplate.support.DistinguishedName;
import net.sf.ldaptemplate.support.DirContextOperations;
import net.sf.ldaptemplate.support.DirContextAdapter;
import javax.naming.Context;
import java.util.*;
/**
* UserDetails manager. Based on the "Person" sample dao from spring-ldap.
*
* @author Luke
* @version $Id$
*/
public class LdapUserDetailsManager implements UserDetailsManager {
private String usernameAttributeName;
private DistinguishedName userDnBase;
private LdapTemplate template;
private String groupBase="cn=groups";
private String groupRoleName="cn";
private String rolePrefix = "ROLE_";
private ContextMapper mapper;
private String[] objectClasses = new String[] {"top", "person", "organizationalPerson", "inetOrgPerson"};
/** Map of user details properties to ldap attributes */
private Map attributeMapping;
public static void main(String[] args) {
ContextSourceInitialDirContextFactory contextFactory = new ContextSourceInitialDirContextFactory("ldap://192.168.101.100:389/dc=acegisecurity,dc=com,dc=au");
contextFactory.setManagerDn("uid=acegiman,cn=people,dc=acegisecurity,dc=com,dc=au");
contextFactory.setManagerPassword("password");
LdapUserDetailsManager mgr = new LdapUserDetailsManager(contextFactory);
InetOrgPerson.Essence user = new InetOrgPerson.Essence();
user.setUsername("jerrymouse");
user.setSn("User");
user.setCn("Test User");
PasswordEncoder pwe = new LdapShaPasswordEncoder();
user.setPassword(pwe.encodePassword("wheresthecheese", null));
mgr.updateUser(user.createUserDetails());
}
public LdapUserDetailsManager(ContextSource contextSource) {
template = new LdapTemplate(contextSource);
userDnBase = new DistinguishedName("cn=users");
Map defaultMapping = new HashMap();
defaultMapping.put("username", "cn");
defaultMapping.put("password", "userPassword");
attributeMapping = Collections.unmodifiableMap(defaultMapping);
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
DistinguishedName dn = buildDn(username);
return (UserDetails) template.lookup(dn, mapper);
}
public void createUser(UserDetails user) {
template.bind(buildDn(user.getUsername()), getUserContextToBind(user), null);
}
public void updateUser(UserDetails user) throws UsernameNotFoundException {
template.rebind(buildDn(user.getUsername()), getUserContextToBind(user), null);
}
public void deleteUser(String username) throws UsernameNotFoundException {
DistinguishedName dn = buildDn(username);
template.unbind(dn);
}
DirContextOperations getUserContextToBind(UserDetails user) {
DirContextAdapter adapter = new DirContextAdapter();
Map attributesToSet = new HashMap();
attributesToSet.put("objectclass", objectClasses);
BeanWrapperImpl userBean = new BeanWrapperImpl(user);
Iterator properties = attributeMapping.keySet().iterator();
while(properties.hasNext()) {
String property = (String) properties.next();
String attribute = (String) attributeMapping.get(property);
List values = (List) attributesToSet.get(attribute);
if(values == null) {
values = new ArrayList();
attributesToSet.put(attribute, values);
}
Object propertyValue = userBean.getPropertyValue(property);
Assert.notNull(propertyValue);
values.add(propertyValue);
}
Iterator attributes = attributesToSet.keySet().iterator();
while(attributes.hasNext()) {
String attributeName = (String) attributes.next();
List values = (List) attributesToSet.get(attributeName);
adapter.setAttributeValues(attributeName, values.toArray());
}
return adapter;
}
public boolean userExists(String username) {
DistinguishedName dn = buildDn(username);
try {
Object obj = template.lookup(dn);
if (obj instanceof Context) {
LdapUtils.closeContext((Context) obj);
}
return true;
} catch(EntryNotFoundException e) {
return false;
}
}
DistinguishedName buildDn(String username) {
DistinguishedName dn = new DistinguishedName(userDnBase);
dn.add(usernameAttributeName, username);
return dn;
}
public void setGroupBase(String groupBase) {
this.groupBase = groupBase;
}
public void setGroupRoleName(String groupRoleName) {
this.groupRoleName = groupRoleName;
}
public void setUserDnBase(String userDnBase) {
this.userDnBase = new DistinguishedName(userDnBase);
}
/**
* Sets the mapping from property names on the UserDetails object to
* directory attributes.
*
* @param attributeMapping the map, keyed by property name.
*/
public void setAttributeMapping(Map attributeMapping) {
Assert.notNull(attributeMapping.get("username"), "Mapping must contain an entry for 'username'");
Assert.notNull(attributeMapping.get("password"), "Mapping must contain an entry for 'password'");
usernameAttributeName = (String) attributeMapping.get("username");
this.attributeMapping = Collections.unmodifiableMap(attributeMapping);
}
}
class UserDetailsContextMapper implements ContextMapper {
private Class type;
private Map attributeMapping;
public UserDetailsContextMapper(Map attributeMapping, Class userDetailsType) {
type = userDetailsType;
this.attributeMapping = attributeMapping;
}
public Object mapFromContext(Object ctx) {
DirContextOperations dirContext = (DirContextOperations) ctx;
DistinguishedName dn = new DistinguishedName(dirContext.getDn());
return null;
}
}