001: package ru.emdev.EmForge.security.ldap;
002:
003: import javax.naming.NamingEnumeration;
004: import javax.naming.NamingException;
005: import javax.naming.directory.Attribute;
006: import javax.naming.directory.Attributes;
007:
008: import org.acegisecurity.GrantedAuthority;
009: import org.acegisecurity.GrantedAuthorityImpl;
010: import org.acegisecurity.ldap.LdapEntryMapper;
011: import org.acegisecurity.userdetails.ldap.LdapUserDetailsMapper;
012: import org.apache.commons.logging.Log;
013: import org.apache.commons.logging.LogFactory;
014: import org.springframework.util.Assert;
015:
016: /** It is copied from LdapUserDetailsMapper class with some minor modifications */
017: public class EmForgeUserDetailsMapper implements LdapEntryMapper {
018: //~ Instance fields ================================================================================================
019:
020: private final Log logger = LogFactory
021: .getLog(LdapUserDetailsMapper.class);
022: private String passwordAttributeName = "userPassword";
023: private String rolePrefix = "ROLE_";
024: private String[] roleAttributes = null;
025: private boolean convertToUpperCase = true;
026:
027: protected String getUserAttributeName() {
028: return "uid";
029: }
030:
031: //~ Methods ========================================================================================================
032:
033: public Object mapAttributes(String dn, Attributes attributes)
034: throws NamingException {
035: EmForgeUserLdap.Essence essence = new EmForgeUserLdap.Essence();
036:
037: essence.setDn(dn);
038: essence.setAttributes(attributes);
039:
040: Attribute userNameAttribute = attributes
041: .get(getUserAttributeName());
042:
043: if (userNameAttribute != null) {
044: essence.setUsername(userNameAttribute.get().toString());
045: }
046:
047: Attribute passwordAttribute = attributes
048: .get(passwordAttributeName);
049:
050: if (passwordAttribute != null) {
051: essence.setPassword(mapPassword(passwordAttribute));
052: }
053:
054: // Map the roles
055: for (int i = 0; (roleAttributes != null)
056: && (i < roleAttributes.length); i++) {
057: Attribute roleAttribute = attributes.get(roleAttributes[i]);
058:
059: if (roleAttribute == null) {
060: logger.debug("Couldn't read role attribute '"
061: + roleAttributes[i] + "' for user " + dn);
062: continue;
063: }
064:
065: NamingEnumeration attributeRoles = roleAttribute.getAll();
066:
067: while (attributeRoles.hasMore()) {
068: GrantedAuthority authority = createAuthority(attributeRoles
069: .next());
070:
071: if (authority != null) {
072: essence.addAuthority(authority);
073: } else {
074: logger
075: .debug("Failed to create an authority value from attribute with Id: "
076: + roleAttribute.getID());
077: }
078: }
079: }
080:
081: return essence;
082: }
083:
084: /**
085: * Extension point to allow customized creation of the user's password from
086: * the attribute stored in the directory.
087: *
088: * @param passwordAttribute the attribute instance containing the password
089: * @return a String representation of the password.
090: */
091: protected String mapPassword(Attribute passwordAttribute)
092: throws NamingException {
093: Object retrievedPassword = passwordAttribute.get();
094:
095: if (!(retrievedPassword instanceof String)) {
096: // Assume it's binary
097: retrievedPassword = new String((byte[]) retrievedPassword);
098: }
099:
100: return (String) retrievedPassword;
101:
102: }
103:
104: /**
105: * Creates a GrantedAuthority from a role attribute. Override to customize
106: * authority object creation.
107: * <p>
108: * The default implementation converts string attributes to roles, making use of the <tt>rolePrefix</tt>
109: * and <tt>convertToUpperCase</tt> properties. Non-String attributes are ignored.
110: * </p>
111: *
112: * @param role the attribute returned from
113: * @return the authority to be added to the list of authorities for the user, or null
114: * if this attribute should be ignored.
115: */
116: protected GrantedAuthority createAuthority(Object role) {
117: if (role instanceof String) {
118: if (convertToUpperCase) {
119: role = ((String) role).toUpperCase();
120: }
121: return new GrantedAuthorityImpl(rolePrefix + role);
122: }
123: return null;
124: }
125:
126: /**
127: * Determines whether role field values will be converted to upper case when loaded.
128: * The default is true.
129: *
130: * @param convertToUpperCase true if the roles should be converted to upper case.
131: */
132: public void setConvertToUpperCase(boolean convertToUpperCase) {
133: this .convertToUpperCase = convertToUpperCase;
134: }
135:
136: /**
137: * The name of the attribute which contains the user's password.
138: * Defaults to "userPassword".
139: *
140: * @param passwordAttributeName the name of the attribute
141: */
142: public void setPasswordAttributeName(String passwordAttributeName) {
143: this .passwordAttributeName = passwordAttributeName;
144: }
145:
146: /**
147: * The names of any attributes in the user's entry which represent application
148: * roles. These will be converted to <tt>GrantedAuthority</tt>s and added to the
149: * list in the returned LdapUserDetails object.
150: *
151: * @param roleAttributes the names of the role attributes.
152: */
153: public void setRoleAttributes(String[] roleAttributes) {
154: Assert.notNull(roleAttributes,
155: "roleAttributes array cannot be null");
156: this .roleAttributes = roleAttributes;
157: }
158:
159: /**
160: * The prefix that should be applied to the role names
161: * @param rolePrefix the prefix (defaults to "ROLE_").
162: */
163: public void setRolePrefix(String rolePrefix) {
164: this.rolePrefix = rolePrefix;
165: }
166:
167: }
|