Modified to use classes from org.acegisecurity.ldap package

This commit is contained in:
Luke Taylor 2006-04-16 14:05:28 +00:00
parent 7f24e209a6
commit bbd250e442
9 changed files with 33 additions and 295 deletions

View File

@ -15,282 +15,21 @@
package org.acegisecurity.providers.ldap;
import java.util.Hashtable;
import java.util.Map;
import java.net.URI;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.CommunicationException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.DirContext;
import org.springframework.util.Assert;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.MessageSource;
import org.springframework.context.support.MessageSourceAccessor;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.AcegiMessageSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Encapsulates the information for connecting to an LDAP server and provides an
* access point for obtaining <tt>DirContext</tt> references.
* <p>
* The directory location is configured using by setting the <tt>url</tt> property.
* This should be in the form <tt>ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org</tt>.
* </p>
* <p>
* To obtain an initial context, the client calls the <tt>newInitialDirContext</tt>
* method. There are two signatures - one with no arguments and one which allows
* binding with a specific username and password.
* </p>
* <p>
* The no-args version will bind anonymously unless a manager login has been configured
* using the properties <tt>managerDn</tt> and <tt>managerPassword</tt>, in which case
* it will bind as the manager user.
* </p>
* <p>
* Connection pooling is enabled by default for anonymous or manager connections, but
* not when binding as a specific user.
* </p>
*
* @see <a href="http://java.sun.com/products/jndi/tutorial/ldap/connect/pool.html">The Java
* tutorial's guide to LDAP connection pooling</a>
* @deprecated moved to org.acegisecurity.ldap
*
* @author Robert Sanders
* @author Luke Taylor
* @version $Id$
*
*/
public class DefaultInitialDirContextFactory implements InitialDirContextFactory,
MessageSourceAware {
public class DefaultInitialDirContextFactory extends org.acegisecurity.ldap.DefaultInitialDirContextFactory {
//~ Static fields/initializers =============================================
private static final Log logger = LogFactory.getLog(DefaultInitialDirContextFactory.class);
private static final String CONNECTION_POOL_KEY = "com.sun.jndi.ldap.connect.pool";
private static final String AUTH_TYPE_NONE = "none";
//~ Instance fields ========================================================
protected MessageSourceAccessor messages = AcegiMessageSource.getAccessor();
/**
* The LDAP url of the server (and root context) to connect to.
* TODO: Allow a backup URL for a replication server.
*/
private String url;
/**
* The root DN. This is worked out from the url.
* It is used by client classes when forming a full DN for
* bind authentication (for example).
*/
private String rootDn;
/**
* If your LDAP server does not allow anonymous searches then
* you will need to provide a "manager" user's DN to log in with.
*/
private String managerDn = null;
/**
* The manager user's password.
*/
private String managerPassword = "manager_password_not_set";
/** Type of authentication within LDAP; default is simple. */
private String authenticationType = "simple";
/**
* The INITIAL_CONTEXT_FACTORY used to create the JNDI Factory.
* Default is "com.sun.jndi.ldap.LdapCtxFactory"; you <b>should not</b>
* need to set this unless you have unusual needs.
*/
private String initialContextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
/** Allows extra environment variables to be added at config time. */
private Map extraEnvVars = null;
/**
* Use the LDAP Connection pool; if true, then the
* LDAP environment property "com.sun.jndi.ldap.connect.pool" is added
* to any other JNDI properties.
*/
private boolean useConnectionPool = true;
//~ Constructors ===========================================================
public DefaultInitialDirContextFactory(String url) {
this.url = url;
Assert.hasLength(url, "An LDAP connection URL must be supplied.");
if (url.startsWith("ldap:") || url.startsWith("ldaps:")) {
URI uri = LdapUtils.parseLdapUrl(url);
rootDn = uri.getPath();
} else {
// Assume it's an embedded server
rootDn = url;
}
if (rootDn.startsWith("/")) {
rootDn = rootDn.substring(1);
}
// This doesn't necessarily hold for embedded servers.
//Assert.isTrue(uri.getScheme().equals("ldap"), "Ldap URL must start with 'ldap://'");
}
//~ Methods ================================================================
/**
* Connects anonymously unless a manager user has been specified, in which case
* it will bind as the manager.
*
* @return the resulting context object.
*/
public DirContext newInitialDirContext() {
if (managerDn != null) {
return newInitialDirContext(managerDn, managerPassword);
}
Hashtable env = getEnvironment();
env.put(Context.SECURITY_AUTHENTICATION, AUTH_TYPE_NONE);
return connect(env);
}
public DirContext newInitialDirContext(String username, String password) {
Hashtable env = getEnvironment();
// Don't pool connections for individual users
if (!username.equals(managerDn)) {
env.remove(CONNECTION_POOL_KEY);
}
env.put(Context.SECURITY_PRINCIPAL, username);
env.put(Context.SECURITY_CREDENTIALS, password);
return connect(env);
}
/**
* @return the Hashtable describing the base DirContext that will be created,
* minus the username/password if any.
*/
protected Hashtable getEnvironment() {
Hashtable env = new Hashtable();
env.put(Context.SECURITY_AUTHENTICATION, authenticationType);
env.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
env.put(Context.PROVIDER_URL, url);
if (useConnectionPool) {
env.put(CONNECTION_POOL_KEY, "true");
}
if ((extraEnvVars != null) && (extraEnvVars.size() > 0)) {
env.putAll(extraEnvVars);
}
return env;
}
private InitialDirContext connect(Hashtable env) {
if (logger.isDebugEnabled()) {
Hashtable envClone = (Hashtable)env.clone();
if (envClone.containsKey(Context.SECURITY_CREDENTIALS)) {
envClone.put(Context.SECURITY_CREDENTIALS, "******");
}
logger.debug("Creating InitialDirContext with environment " + envClone);
}
try {
return new InitialDirContext(env);
} catch(CommunicationException ce) {
throw new LdapDataAccessException(messages.getMessage(
"DefaultIntitalDirContextFactory.communicationFailure",
"Unable to connect to LDAP server"), ce);
} catch(javax.naming.AuthenticationException ae) {
throw new BadCredentialsException(messages.getMessage(
"DefaultIntitalDirContextFactory.badCredentials",
"Bad credentials"), ae);
} catch (NamingException nx) {
throw new LdapDataAccessException(messages.getMessage(
"DefaultIntitalDirContextFactory.unexpectedException",
"Failed to obtain InitialDirContext due to unexpected exception"), nx);
}
}
/**
* Returns the root DN of the configured provider URL. For example,
* if the URL is <tt>ldap://monkeymachine.co.uk:389/dc=acegisecurity,dc=org</tt>
* the value will be <tt>dc=acegisecurity,dc=org</tt>.
*
* @return the root DN calculated from the path of the LDAP url.
*/
public String getRootDn() {
return rootDn;
}
public void setAuthenticationType(String authenticationType) {
Assert.hasLength(authenticationType, "LDAP Authentication type must not be empty or null");
this.authenticationType = authenticationType;
}
public void setInitialContextFactory(String initialContextFactory) {
Assert.hasLength(initialContextFactory, "Initial context factory name cannot be empty or null");
this.initialContextFactory = initialContextFactory;
}
/**
* @param managerDn The name of the "manager" user for default authentication.
*/
public void setManagerDn(String managerDn) {
Assert.hasLength(managerDn, "Manager user name cannot be empty or null.");
this.managerDn = managerDn;
}
/**
* @param managerPassword The "manager" user's password.
*/
public void setManagerPassword(String managerPassword) {
Assert.hasLength(managerPassword, "Manager password must not be empty or null.");
this.managerPassword = managerPassword;
}
/**
* @param extraEnvVars extra environment variables to be added at config time.
*/
public void setExtraEnvVars(Map extraEnvVars) {
Assert.notNull(extraEnvVars, "Extra environment map cannot be null.");
this.extraEnvVars = extraEnvVars;
}
public void setMessageSource(MessageSource messageSource) {
this.messages = new MessageSourceAccessor(messageSource);
}
/**
* Connection pooling is enabled by default for anonymous or "manager"
* connections when using the default Sun provider. To disable all
* connection pooling, set this property to false.
*
* @param useConnectionPool whether to pool connections for non-specific users.
*/
public void setUseConnectionPool(boolean useConnectionPool) {
this.useConnectionPool = useConnectionPool;
public DefaultInitialDirContextFactory(String providerUrl) {
super(providerUrl);
}
}

View File

@ -15,30 +15,14 @@
package org.acegisecurity.providers.ldap;
import javax.naming.directory.DirContext;
/**
* Access point for obtaining LDAP contexts.
*
* @see DefaultInitialDirContextFactory
* @deprecated moved to org.acegisecurity.ldap
*
* @author Luke Taylor
* @version $Id$
*/
public interface InitialDirContextFactory {
/**
* Provides an initial context without specific user information.
*/
DirContext newInitialDirContext();
/**
* Provides an initial context by binding as a specific user.
*/
DirContext newInitialDirContext(String userDn, String password);
/**
* @return The DN of the contexts returned by this factory.
*/
String getRootDn();
public interface InitialDirContextFactory extends org.acegisecurity.ldap.InitialDirContextFactory {
}

View File

@ -17,11 +17,14 @@ package org.acegisecurity.providers.ldap;
import org.acegisecurity.providers.dao.AbstractUserDetailsAuthenticationProvider;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.*;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.User;
import org.acegisecurity.AuthenticationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import javax.naming.directory.Attributes;
@ -143,7 +146,7 @@ public class LdapAuthenticationProvider extends AbstractUserDetailsAuthenticatio
}
String password = (String)authentication.getCredentials();
Assert.hasLength(password, "Null or empty password was supplied in authentication token");
Assert.notNull(password, "Null password was supplied in authentication token");
LdapUserInfo ldapUser = authenticator.authenticate(username, password);

View File

@ -15,6 +15,8 @@
package org.acegisecurity.providers.ldap;
import org.acegisecurity.ldap.LdapUserInfo;
/**
* The strategy interface for locating and authenticating an Ldap user.
* <p>

View File

@ -16,6 +16,7 @@
package org.acegisecurity.providers.ldap;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.ldap.LdapDataAccessException;
import javax.naming.directory.Attributes;
@ -38,7 +39,7 @@ public interface LdapAuthoritiesPopulator {
* @param userDn the full DN of the user
* @param userAttributes the user's LDAP attributes that were retrieved from the directory.
* @return the granted authorities for the given user.
* @throws LdapDataAccessException if there is a problem accessing the directory.
* @throws org.acegisecurity.ldap.LdapDataAccessException if there is a problem accessing the directory.
*/
GrantedAuthority[] getGrantedAuthorities(String username, String userDn, Attributes userAttributes)
throws LdapDataAccessException;

View File

@ -16,9 +16,10 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.providers.ldap.LdapAuthenticator;
import org.acegisecurity.providers.ldap.InitialDirContextFactory;
import org.acegisecurity.providers.ldap.LdapUserSearch;
import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.ldap.LdapUserSearch;
import org.acegisecurity.AcegiMessageSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
import org.springframework.context.support.MessageSourceAccessor;

View File

@ -15,14 +15,19 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.providers.ldap.*;
import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.LdapDataAccessException;
import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.BadCredentialsException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import javax.naming.NamingException;
import java.util.Iterator;
/**

View File

@ -15,13 +15,15 @@
package org.acegisecurity.providers.ldap.authenticator;
import org.acegisecurity.providers.ldap.LdapUserInfo;
import org.acegisecurity.providers.ldap.LdapUtils;
import org.acegisecurity.providers.ldap.InitialDirContextFactory;
import org.acegisecurity.ldap.LdapUserInfo;
import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -30,6 +32,7 @@ import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attribute;
import java.util.Iterator;
/**

View File

@ -16,9 +16,9 @@
package org.acegisecurity.providers.ldap.populator;
import org.acegisecurity.providers.ldap.LdapAuthoritiesPopulator;
import org.acegisecurity.providers.ldap.LdapDataAccessException;
import org.acegisecurity.providers.ldap.InitialDirContextFactory;
import org.acegisecurity.providers.ldap.LdapUtils;
import org.acegisecurity.ldap.LdapDataAccessException;
import org.acegisecurity.ldap.InitialDirContextFactory;
import org.acegisecurity.ldap.LdapUtils;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.apache.commons.logging.Log;