Spring 3.1 Tomcat 6. *
I am working on creating Spring 3.1 webapp authentication using LDAP.
I tested the LDAP credentials (username, password, ldap url, search pattern) using a Java program developed by JNDI that I wrote (given below). This program worked, resetting all user attributes, including the password, which seems to be encrypted on the LDAP server.
When I try to log in with the same credentials in Spring 3.1, I get the "Bad Credentials" error message.
I got this message in the logs:
DEBUG [org.springframework.security.authentication.ProviderManager:authenticate] (ProviderManager.java:152) - Authentication attempt using org.springframework.security.ldap.authentication.LdapAuthenticationProvider DEBUG [org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider:authenticate] (AbstractLdapAuthenticationProvider.java:51) - Processing authentication request for user: John.A.Smith DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:bindWithDn] (BindAuthenticator.java:108) - Attempting to bind as uid=John.A.Smith,ou=People,o=acme.com,o=acme.com DEBUG [org.springframework.security.ldap.DefaultSpringSecurityContextSource$1:setupEnvironment] (DefaultSpringSecurityContextSource.java:76) - Removing pooling flag for user uid=John.A.Smith,ou=People,o=acme.com,o=acme.com DEBUG [org.springframework.security.ldap.authentication.BindAuthenticator:handleBindException] (BindAuthenticator.java:152) - Failed to bind as uid=John.A.Smith,ou=People,o=acme.gov: org.springframework.ldap.AuthenticationException: [LDAP: error code 32 - No Such Object]; nested exception is javax.naming.AuthenticationException: [LDAP: error code 32 - No Such Object] DEBUG [org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter:unsuccessfulAuthentication] (AbstractAuthenticationProcessingFilter.java:340) - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
In my * -security.xml, I tried using tags to do password comparison and encoding, but that didn't help. I tried using md4, md5, plaintext, sha, sha-256, {ssha}, {sha} to no avail.
<s:authentication-manager> <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" > <s:password-compare hash="md5"> <s:password-encoder hash="md5"/> </s:password-compare> </s:ldap-authentication-provider> </s:authentication-manager>
My network group is a large, slow, bureaucratic organization. Is there a way I can determine which encoding they use, if any, without accessing them?
Any ideas of things I could check?
This is my * -security.xml in my last attempt and java LDAP demo that I CAN connect to
Thanks.
My * -security.xml file:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <s:http auto-config="true" use-expressions="true"> **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** <s:form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/loginfailed" /> <s:logout logout-success-url="/logout" /> </s:http> <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> <s:authentication-manager> <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People,o=noaa.gov" /> </s:authentication-manager> </beans>
The following is a JAP type JNDI Java program that works with the same credentials:
import javax.naming.*; import javax.naming.directory.*; import java.util.*; import java.sql.*; public class LDAPDEMO { public static void main(String args[]) { String lcf = "com.sun.jndi.ldap.LdapCtxFactory"; String ldapurl = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"; String loginid = "John.A.Smith"; String password = "passowordforjohn"; DirContext ctx = null; Hashtable env = new Hashtable(); Attributes attr = null; Attributes resultsAttrs = null; SearchResult result = null; NamingEnumeration results = null; int iResults = 0; env.put(Context.INITIAL_CONTEXT_FACTORY, lcf); env.put(Context.PROVIDER_URL, ldapurl); env.put(Context.SECURITY_PROTOCOL, "ssl"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "uid=" + loginid + ",ou=People,o=acme.com"); env.put(Context.SECURITY_CREDENTIALS, password); try { ctx = new InitialDirContext(env); attr = new BasicAttributes(true); attr.put(new BasicAttribute("uid",loginid)); results = ctx.search("ou=People",attr); while (results.hasMore()) { result = (SearchResult)results.next(); resultsAttrs = result.getAttributes(); for (NamingEnumeration enumAttributes = resultsAttrs.getAll(); enumAttributes.hasMore();) { Attribute a = (Attribute)enumAttributes.next(); System.out.println("attribute: " + a.getID() + " : " + a.get().toString()); }
Decision
This comment from Luke Taylor helped me set up my configuration:
Your configuration is incorrect in that you have "o = acme.com" in the LDAP server URLs and also use "o = acme.com" in the user DN template.
I took "o = acme.com" from the DN template and worked as LDAP. I initially put "o = acme.com" in both the LDAP URL and the DN pattern, because I am new to Spring 3.1 and LDAP, and it looks like it was / was done in the Java version of the JNDI demo The LDAP I wrote based on the old code that I am replacing.
Here is the final working version of my * -security.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:s="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <s:http auto-config="true" use-expressions="true"> **<s:intercept-url pattern="/welcome*" access="isAuthenticated()" />** <s:form-login login-page="/login" default-target-url="/welcome" authentication-failure-url="/loginfailed" /> <s:logout logout-success-url="/logout" /> </s:http> <s:ldap-server url = "ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> <s:authentication-manager> <s:ldap-authentication-provider user-dn-pattern="uid={0},ou=People" /> </s:authentication-manager> </beans>
I am going to examine his other comment and see if I can enter the password encoding again or if I need to.