Spring 3.1 LDAP Authentication Process: Bad Credentials msg When Credentials Are Good

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()); }// end for loop iResults++; }// end while loop System.out.println("iResults == " + iResults); }// end try catch (Exception e) { e.printStackTrace(); } }// end function main() }// end class LDAPDEMO 

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.

+6
source share
2 answers

Your Java example uses standard authentication, but you set up the Spring security configuration for the LDAP comparison operation on the user password. This will fail because the LDAP server does not use the same password encoding format as Spring Security MD5 encoder. For a successful comparison operation, the stored value must correspond to the string that is sent to the directory. In most cases, you want to use standard LDAP authentication (bind). You will probably need a bean configuration for the authentication provider. Try using:

 <s:ldap-server id="contextSource" url="ldap://ldap-itc.sam.acme.com:636/o=acme.com"/> <bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"> <constructor-arg> <bean class="org.springframework.security.ldap.authentication.BindAuthenticator"> <constructor-arg ref="contextSource"/> <property name="userDnPatterns"> <list><value>uid={0},ou=People</value></list> </property> </bean> </constructor-arg> <constructor-arg> <bean class="org.springframework.security.ldap.authentication.NullLdapAuthoritiesPopulator"/> </constructor-arg> <property name="authoritiesMapper"> <bean class="class="org.springframework.security.core.authority.mapping"> <property name="defaultAuthority" value="ROLE_USER" /> </bean> </property> </bean> <s:authentication-manager> <s:authentication-manager ref="ldapAuthProvider" /> </s:authentication-manager> 

I would recommend you also read the LDAP chapter of the reference guide .

Also, if you want to know why authentication fails, it is best to find the log for the LDAP server itself. If you do not have full access, find out how it is configured and uses a local server (for example, OpenLDAP), where you have full control.

+3
source

I will try my luck. A few weeks ago I had a similar problem. No errors, fixed user / password and Bad Credentials error.

First, I recommend that you activate the debugging level for spring security. You will get more information. In my case, it helped me to understand that the problem was that my user had no role, and spring caused an error as "bad credentials". This may be your case. Check it out.

In any case, bad credentials do not mean that the user / password is incorrect.

EDIT: to activate the debugging level using log4j:

 <logger name="org.springframework.security"> <level value="DEBUG" /> </logger> 

In your configuration, you can read that an administrator role is required to access the welcome page: ROLE_ADMIN. If you don't need roles, you should try something like this:

 <s:intercept-url pattern="/welcome*" access="isAuthenticated()" /> 
0
source

Source: https://habr.com/ru/post/911898/


All Articles