2011-03-10 42 views
7

Estoy intentando autenticar y luego consultar nuestro LDAP corporativo utilizando Spring LDAP y Spring security. Me las arreglé para hacer el trabajo de autenticación, pero cuando intento ejecutar la búsqueda siempre me dan la siguiente excepciónSpring LDAP - enlace para una conexión exitosa

In order to perform this operation a successful bind must be completed on the connection

Después de mucha investigación Tengo la teoría de que después de un autentico y antes de que pueda consultar lo que necesito para unirse a la conexión. Simplemente no sé qué y cómo?

Solo por mencionar que puedo navegar y buscar con éxito nuestro LDAP usando JXplorer, así que mis parámetros son correctos.

Aquí es parte de mi securityContext.xml

<security:http auto-config='true'> 
    <security:intercept-url pattern="/reports/goodbye.html" 
      access="ROLE_LOGOUT" /> 
    <security:intercept-url pattern="/reports/**" access="ROLE_USER" /> 
    <security:http-basic /> 
    <security:logout logout-url="/reports/logout" 
      logout-success-url="/reports/goodbye.html" /> 
</security:http> 
<security:ldap-server url="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /> 
<security:authentication-manager> 
    <security:authentication-provider ref="ldapAuthProvider"> 
</security:authentication-provider> 
</security:authentication-manager> 
<!-- Security beans --> 
<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
    <constructor-arg value="ldap://s140.foo.com:1389/dc=td,dc=foo,dc=com" /> 
</bean> 
<bean id="ldapAuthProvider" 
    class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider"> 
    <constructor-arg> 
     <bean class="foo.bar.reporting.server.security.ldap.LdapAuthenticatorImpl"> 
      <property name="contextFactory" ref="contextSource" /> 
      <property name="principalPrefix" value="TD\" /> 
      <property name="employee" ref="employee"></property> 
     </bean> 
    </constructor-arg> 
    <constructor-arg> 
     <bean class="foo.bar.reporting.server.security.ldap.LdapAuthoritiesPopulator" /> 
    </constructor-arg> 
</bean> 
<!-- DAOs --> 
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate"> 
    <constructor-arg ref="contextSource" /> 

He aquí el fragmento de código de LdapAuthenticatorImpl que realiza la autenticación. No hay problema aquí:

@Override 
public DirContextOperations authenticate(final Authentication authentication) { 
    // Grab the username and password out of the authentication object. 
    final String name = authentication.getName(); 
    final String principal = this.principalPrefix + name; 
    String password = ""; 
    if (authentication.getCredentials() != null) { 
     password = authentication.getCredentials().toString(); 
    } 
    if (!("".equals(principal.trim())) && !("".equals(password.trim()))) { 
     final InitialLdapContext ldapContext = (InitialLdapContext) 
    this.contextFactory.getContext(principal, password); 
     // We need to pass the context back out, so that the auth provider 
     // can add it to the Authentication object. 
     final DirContextOperations authAdapter = new DirContextAdapter(); 
     authAdapter.addAttributeValue("ldapContext", ldapContext); 
     this.employee.setqId(name); 
     return authAdapter; 
    } else { 
     throw new BadCredentialsException("Blank username and/or password!"); 
    } 
} 

Y aquí hay otro fragmento de código EmployeeDao con mi inútil intento de consulta:

public List<Employee> queryEmployeesByName(String query) 
    throws BARServerException { 
    AndFilter filter = new AndFilter(); 
    filter.and(new EqualsFilter("objectclass", "person")); 
    filter.and(new WhitespaceWildcardsFilter("cn", query)); 
    try { 
     // the following line throws bind exception 
     List result = ldapTemplate.search(BASE, filter.encode(), 
      new AttributesMapper() { 
      @Override 
      public Employee mapFromAttributes(Attributes attrs) 
       throws NamingException { 
       Employee emp = new Employee((String) attrs.get("cn").get(), 
        (String) attrs.get("cn").get(), 
         (String) attrs.get("cn").get()); 
       return emp; 
      } 
     }); 
     return result; 
    } catch (Exception e) { 
     throw new BarServerException("Failed to query LDAP", e); 
    } 
} 

Y por último - la excepción que estoy recibiendo

org.springframework.ldap.UncategorizedLdapException: 
    Uncategorized exception occured during LDAP processing; nested exception is 
    javax.naming.NamingException: [LDAP: error code 1 - 00000000: LdapErr: 
    DSID-0C090627, comment: In order to perform this operation a successful bind 
    must be completed on the connection., data 0, vece]; remaining name 
    'DC=TD,DC=FOO,DC=COM' 
+0

Sé que esto es antiguo, pero @Bostone puede ayudarme a resolver esto.Obtengo exactamente la misma excepción, sin embargo, estoy obteniendo este error en la página de inicio de sesión donde el usuario ingresa las credenciales. El ldap regresa exitosamente cuando se ingresa el nombre de usuario y la contraseña correctos pero recibo el siguiente error: [LDAP: código de error 1 - 00000000: LdapErr: DSID-0C090627, comentario: para realizar esta operación se debe completar un enlace exitoso en la conexión. , datos 0, vece]; remanching name '' – user1647708

+0

@ user1647708 por favor vea mi respuesta a continuación. Funcionó para mí – Bostone

Respuesta

4

Parece al igual que su LDAP está configurado para no permitir una búsqueda sin vincularla (sin enlace anónimo). También ha implementado PasswordComparisonAuthenticator y no BindAuthenticator a authenticate en LDAP.

Puede intentar modificar su método queryEmployeesByName() para vincular y buscar, mirando algunos ejemplos en el doc.

+0

Esto parece un comentario, ¿qué sugieres? Sé que es posible porque puedo usar JXplorer (que es una aplicación de Java) para conectar y buscar LDAP. No puedo entender cómo enlazar. Creo que probé BindAuthenticator en el pasado y terminé con la misma excepción – Bostone

+0

@ Droidln.net. Editó la respuesta con una sugerencia explícita. – Raghuram

+0

Esto es muy doc que utilicé para codificar la autenticación. Cuando están hablando de vincular/desvincular significan insertar/borrar registros en ese ejemplo particular – Bostone

3

Voy a aceptar la respuesta @Raghuram principalmente porque me hizo pensar en la dirección correcta.

¿Por qué mi código estaba fallando? Resultó - la forma en que lo conecté, estaba tratando de realizar una búsqueda anónima que está prohibida por el sistema - de ahí el error.

¿Cómo volver a conectar el ejemplo anterior al trabajo? Lo primero (y feo) es que debe proporcionar el nombre de usuario y la contraseña del usuario que se utilizará para acceder al sistema. Muy contrario a la intuición, incluso cuando inicia sesión y se autentica, incluso si está usando el sistema BindAuthenticator, no intentará reutilizar sus credenciales. Gorrón. Así que hay que atenerse 2 parámetros en contextSource definición de este modo:

<bean id="contextSource" class="org.springframework.security.ldap.DefaultSpringSecurityContextSource"> 
    <constructor-arg value="ldap://foo.com:389/dc=td,dc=foo,dc=com" /> 
    <!-- TODO - need to hide this or encrypt a password --> 
    <property name="userDn" value="CN=admin,OU=Application,DC=TD,DC=FOO,DC=COM" /> 
    <property name="password" value="blah" /> 
</bean> 

Hacer eso me permitió sustituir implementación personalizada de autenticador con genéricos BindAuthenticator y luego mi búsqueda de Java comenzó a trabajar

+1

¿Ha establecido los valores para 'userDn' y' password' en los valores reales? Quiero decir que si hago esto, todos lo verán en texto sin formato. ¿Cómo puedo leerlo, por ejemplo, desde un formulario de inicio de sesión? –

0

Tengo el mismo error, no pudo encontrar una solución. Finalmente cambié la identidad del grupo de aplicaciones al servicio de red y todo funcionó como un amuleto. (tengo autenticación de Windows y anónimo habilitado en mi sitio)

Cuestiones relacionadas