2012-03-28 26 views
6

Primavera 3.1 Tomcat 6. *Primavera 3.1 Proceso de autenticación LDAP: "Bad credenciales" msg Cuando Credenciales son buenos

estoy trabajando en hacer una aplicación web de Primavera 3.1, la autenticación con LDAP.

Probé las credenciales de LDAP (nombre de usuario, contraseña, URL de ldap, patrón de búsqueda) con un programa Java de estilo JNDI que escribí (citado a continuación). Ese programa funcionó, eliminó todos los atributos de los usuarios, incluida la contraseña, que parece estar encriptada en el servidor LDAP.

Cuando intento iniciar sesión con las mismas credenciales en Spring 3.1, aparece el mensaje de error "Bad Credentials".

Tengo este mensaje en los registros:

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 

En mi * -security.xml He intentado utilizar las etiquetas para hacer una comparación contraseña y codificación ocurren, pero no sirvió de nada. Intenté usar md4, md5, texto plano, sha, sha-256, {ssha}, {sha} en vano.

<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> 

Mi grupo de redes es una gran org, lento, burocrático. ¿Hay alguna forma de saber qué codificación usan, si es que hay alguna, sin contactarlos?

¿Alguna idea de cosas que podría ver?

Ésta es mi * -security.xml como de mi último intento y la demo de Java LDAP pude conectar con

Gracias.

Mi archivo * -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,o=noaa.gov" /> 
    </s:authentication-manager> 

</beans> 

Aquí es el programa de estilo de JNDI LDAP de Java que funciona con las mismas credenciales:

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 

Solución


Este comentario de Lucas Taylor ayudó a conseguir mi trabajo de configuración:

Su configuración está mal en que tiene "o = acme.com" en la URL del servidor LDAP y también están utilizando " o = acme.com "en el patrón DN de usuario.

Saqué el "o = acme.com" del patrón DN y funcionó el LDAP. Originalmente había puesto "o = acme.com" tanto en el URL LDAP como en el patrón DN porque soy nuevo en Spring 3.1 y LDAP, y eso es similar a cómo se hizo/se hizo en la versión Java JNDI del LDAP demo que escribí en base al código heredado que estoy reemplazando.

Aquí está la versión final y funcional de mi * -seguridad.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> 

Voy a explorar su otro comentario y ver si puedo poner la contraseña de codificación de nuevo o si es necesario.

+0

Otra nota. No puede volver a poner la contraseña de codificación, ya que no sabe qué algoritmo está usando el servidor y, en la práctica, podría estar utilizando más de uno. Las contraseñas hash se trata de proteger la base de datos de contraseñas al hacerla más difícil de leer. No se trata de hacer la autenticación del cliente más segura (encontrará muchas discusiones al respecto en SO). Si desea evitar el espionaje en la red desde su aplicación al servidor LDAP, entonces usar una conexión SSL es probablemente la opción más simple. –

Respuesta

3

Su ejemplo de Java está utilizando la autenticación se unen estándar, pero ha establecido la configuración de la primavera de Seguridad para hacer una LDAP compare operation de la contraseña del usuario. Esto fallará porque el servidor LDAP no está utilizando el mismo formato de codificación de contraseña que el codificador MD5 de Spring Security. Para que una operación de comparación tenga éxito, el valor almacenado debe coincidir con la cadena que se envía al directorio. En la mayoría de los casos, desea utilizar la autenticación estándar LDAP (bind). Probablemente necesites usar una configuración de bean para el proveedor de autenticación. Trate de usar:

<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> 

que recomiendo leer también the LDAP chapter of the reference manual.

Además, si desea saber por qué una autenticación está fallando, el mejor lugar para averiguar es el registro del servidor LDAP. Si no tiene acceso completo, descubra cómo está configurado y use un servidor local (como OpenLDAP) donde tenga control total.

+0

Hola Luke. Leí el capítulo de LDAP en Spring 3.1 varias veces. Es breve y soy nuevo en LDAP y en Spring. Quiero asegurarme de que entiendo tu comentario. Si elimino las etiquetas , me desplegaré para usar el enlace estándar, como el programa Java citado es y NO voy a hacer una comparación de contraseña en absoluto? ¿Spring hace una comparación de contraseña por defecto? ¿Tendría que configurar algo para que NO lo haga? – Steve

+0

Si no los contactas, no puedes, y comparar contraseñas no es una buena idea si son codificadas (el caso podría ser diferente, por ejemplo). Debería usar autenticación de enlace ya que ya ha demostrado que funciona y olvida la comparación de contraseña. Normalmente solo se usa cuando bind está deshabilitado. ¿Intentó la configuración que proporcioné? Si es así, ¿qué pasó? –

+0

Luke, a la luz de sus comentarios, cambié mi * server.xml y mi publicación original completa. Necesito estudiar tu configuración por un momento. Si es posible, me gustaría encontrar una manera de escribirlo estilo Spring 3.1. Le daré una oportunidad y le dejaré saber cómo funciona. Gracias una tonelada. – Steve

0

Voy a probar suerte. Hace algunas semanas tuve un problema similar. Sin errores, error de usuario/contraseña y error de credenciales incorrectas.

Primero, le recomiendo que active el nivel de depuración para la seguridad de primavera. Obtendrás más información. En mi caso, esto me ayudó a ver que el problema era que mi usuario no tenía ningún rol asociado y Spring lo estaba traduciendo como error de "malas credenciales". Podría ser tu caso. Revisalo.

De todos modos, malas credenciales no significa siempre que el usuario/pase incorrecto.

EDIT: Para activar el nivel de depuración mediante log4j:

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

Durante la parametrización, se puede leer que el acceso a la página de bienvenida requiere rol de administrador: ROLE_ADMIN. Si no desea que los papeles, usted debe intentar algo como esto:

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

Soy nuevo en Spring y LDAP. ¿Cómo puedo activar el nivel de depuración en Spring Security? ¿Es posible NO asociar un rol con un usuario y, en caso afirmativo, cómo? ¿Puedo asociar un rol neutral con el usuario? Realmente no tenemos roles para los usuarios. – Steve

+0

He editado la respuesta. Si no quiere roles, no asocie uno al acceso. – jddsantaella

+0

Probé el nuevo valor de acceso que sugirió. Ningún cambio. ¿Dónde pondría ese logger xml que citó arriba? – Steve

Cuestiones relacionadas