Attached is a patch that makes it easier to extend
LdapPasswordAuthenticationDao. It changes the field variables from
private to protected, and adds a protected toUserDetails() method.
This allows LdapPasswordAuthenticationDao to be extended, and simply
override the toUserDetails method to populate a custom UserDetails
implementation with attributes from LDAP.
Even with these changes, acegi's LDAP support still feels like a hack.
I'm not real familiar with JNDI, so I'm going to spend some time
learning that and hopefully I'll be able to contribute more in this
area in the near future. But I definately think this piece needs a
little more attention.
Brandon
Index: sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/InitialDirContextFactoryBean.java
===================================================================
RCS file: /home/bkeepers/software/java/spring/acegisecurity/acegisecurity/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/InitialDirContextFactoryBean.java,v
retrieving revision 1.3
diff -u -r1.3 InitialDirContextFactoryBean.java
--- sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/InitialDirContextFactoryBean.java 17 Nov 2005 00:55:48 -0000 1.3
+++ sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/InitialDirContextFactoryBean.java 8 Dec 2005 01:43:38 -0000
@@ -218,5 +218,13 @@
public void setExtraEnvVars(Map extraEnvVars) {
this.extraEnvVars = extraEnvVars;
}
+
+ public boolean isConnectionPoolEnabled() {
+ return connectionPoolEnabled;
+ }
+
+ public void setConnectionPoolEnabled(boolean connectionPoolEnabled) {
+ this.connectionPoolEnabled = connectionPoolEnabled;
+ }
}
Index: sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java
===================================================================
RCS file: /home/bkeepers/software/java/spring/acegisecurity/acegisecurity/sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java,v
retrieving revision 1.11
diff -u -r1.11 LdapPasswordAuthenticationDao.java
--- sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java 29 Nov 2005 13:10:08 -0000 1.11
+++ sandbox/src/main/java/org/acegisecurity/providers/dao/ldap/LdapPasswordAuthenticationDao.java 8 Dec 2005 03:59:09 -0000
@@ -71,7 +71,7 @@
*/
public class LdapPasswordAuthenticationDao extends InitialDirContextFactoryBean implements PasswordAuthenticationDao {
- private static final Log logger = LogFactory.getLog(LdapPasswordAuthenticationDao.class);
+ protected final Log logger = LogFactory.getLog(getClass());
public static final String BAD_CREDENTIALS_EXCEPTION_MESSAGE = "Invalid username, password or server configuration (JNDI Context).";
@@ -84,7 +84,7 @@
* Active Directory style LDAP: "[EMAIL PROTECTED]"
* </p>
*/
- private MessageFormat usernameFormat = new MessageFormat("cn={0}");
+ protected MessageFormat usernameFormat = new MessageFormat("cn={0}");
/** Message format used to create the Name within the LDAP Context
* from which role information will be retrieved.
@@ -94,20 +94,20 @@
* <p>Example: "uid={0},ou=users"</p>
*
*/
- private MessageFormat userLookupNameFormat = null;
+ protected MessageFormat userLookupNameFormat = null;
/** List of LDAP Attributes which contian role name information. */
- private String[] roleAttributes = {"memberOf"};
+ protected String[] roleAttributes = {"memberOf"};
/** The role, which if non-null, will be grated the user if the user has no other roles. */
- private String defaultRole = null;
+ protected String defaultRole = null;
public UserDetails loadUserByUsernameAndPassword(String username, String password) throws DataAccessException, BadCredentialsException {
if ((password == null) || (password.length() == 0)) {
throw new BadCredentialsException("Empty password");
}
- String ldapUsername = (null == usernameFormat) ? username : usernameFormat.format( new Object[]{username} );
+ String ldapUsername = getUsername(username);
if (logger.isDebugEnabled()) {
logger.debug("Connecting to " + this.getUrl() + " as " + ldapUsername);
}
@@ -121,16 +121,30 @@
if (null == dirContext) {
throw new BadCredentialsException(BAD_CREDENTIALS_EXCEPTION_MESSAGE);
}
-
+
+ UserDetails user;
+ try {
+ user = toUserDetails(username, password, dirContext);
+ } catch (NamingException e) {
+ throw new DataAccessResourceFailureException("Unable to retrieve user information from LDAP Server.", e);
+ }
+
+ return user;
+ }
+
+ /**
+ * Create an instance of UserDetails.
+ *
+ * @param username username provided by user
+ * @param password password provided by user
+ * @param dirContext a DirContext to use to populate the result object
+ * @throws NamingException
+ */
+ protected UserDetails toUserDetails(String username, String password, DirContext dirContext) throws NamingException {
String[] roles = null;
if (null != roleAttributes) {
- try {
- String userContextName = (null == userLookupNameFormat) ? "" :
- userLookupNameFormat.format(new Object[]{username, ldapUsername});
- roles = getRolesFromContext(dirContext, userContextName);
- } catch (NamingException e) {
- throw new DataAccessResourceFailureException("Unable to retrieve role information from LDAP Server.", e);
- }
+ String userContextName = getUserLookupName(username);
+ roles = getRolesFromContext(dirContext, userContextName);
}
if ((null == roles) && (null != defaultRole)) {
roles = new String[] {defaultRole};
@@ -171,6 +185,28 @@
return ga;
}
+ /**
+ * Get the formatted user lookup name
+ * @param username Username provided by user
+ * @return a formatted user lookup name
+ */
+ protected String getUserLookupName(String username) {
+ return (null == userLookupNameFormat) ? "" :
+ userLookupNameFormat.format(
+ new Object[]{username, getUsername(username)});
+ }
+
+ /**
+ * Get the formatted username
+ *
+ * @param username Username provided by the user
+ * @return a formatted username
+ */
+ protected String getUsername(String username) {
+ return (null == usernameFormat) ? username :
+ usernameFormat.format( new Object[]{username} );
+ }
+
/**
*
* @param ctx The LDAP DirContext retrieved by the user login.