Hi all,
I'm currently implementing/configuring the LDAP authentication of a Java web application using Spring Security 3.0. I'm using Microsoft AD LDS as LDAP server and chose the Spring's BindAuthenticator. I found out that the authentication only works if the authenticated user is a member of the partition's Readers role. The BindAuthenticator tries to read the user's attributes after the authentication, which seems reasonable in scenarios where authorities are retrieved from the directory service.
Being new to LDAP and AD, is this an acceptable practise when the application is integrated in an existing AD structure? Can fine-tune an give the user dns only read permissions for their own attributes rather than adding them to the Reader group?
Thanks Thomas
Edit 3/8/2010: Here's what I ended up doing: I copied Spring's BindAuthenticator (the whole class) and changed the method bindWithDn() as below. Differences are marked with DIFF.
private DirContextOperations bindWithDn(String userDn, String username, String password) {
BaseLdapPathContextSource ctxSource = (BaseLdapPathContextSource) getContextSource();
DistinguishedName fullDn = new DistinguishedName(userDn);
fullDn.prepend(ctxSource.getBaseLdapPath());
logger.debug("Attempting to bind as " + fullDn);
DirContext ctx = null;
try {
ctx = getContextSource().getContext(fullDn.toString(), password);
// Check for password policy control
PasswordPolicyControl ppolicy = PasswordPolicyControlExtractor.extractControl(ctx);
// *DIFF* Attributes attrs = ctx.getAttributes(userDn, getUserAttributes());
DirContextAdapter result = new DirContextAdapter(null, new DistinguishedName(userDn), // *DIFF*
ctxSource.getBaseLdapPath());
if (ppolicy != null) {
result.setAttributeValue(ppolicy.getID(), ppolicy);
}
return result;
} catch (NamingException e) {
// This will be thrown if an invalid user name is used and the method may
// be called multiple times to try different names, so we trap the exception
// unless a subclass wishes to implement more specialized behaviour.
if ((e instanceof org.springframework.ldap.AuthenticationException)
|| (e instanceof org.springframework.ldap.OperationNotSupportedException)) {
handleBindException(userDn, username, e);
} else {
throw e;
}
// *DIFF* } catch (javax.naming.NamingException e) {
// *DIFF* throw LdapUtils.convertLdapException(e);
} finally {
LdapUtils.closeContext(ctx);
}
return null;
}