2012-09-10 19 views
14

Estoy manteniendo algún código LDAP heredado de Java. No sé casi nada sobre LDAP.Java, LDAP: ¿Hacer que no ignore las contraseñas en blanco?

El programa siguiente básicamente solo envía el ID de usuario y la contraseña al servidor LDAP, recibe una notificación de vuelta si las credenciales son buenas. Si es así, imprime los atributos LDAP recibidos del servidor LDAP, si no imprime una excepción.

Todo funciona bien si se proporciona una contraseña incorrecta. Se lanza una excepción de "credenciales inválidas". Sin embargo, si se envía una contraseña en blanco al servidor LDAP, aún se realizará la autenticación, los atributos LDAP seguirán siendo devueltos.

¿Es esta situación infeliz debido a que el servidor LDAP permite contraseñas en blanco, o es necesario ajustar el código siguiente para que una contraseña en blanco se alimente al servidor LDAP de forma que se rechace?

Tengo validación de datos en su lugar. Me lo quité en un entorno de prueba para resolver otro problema y noté este problema. Preferiría no tener este problema debajo de la validación de datos.

Gracias de antemano por cualquier información

import javax.naming.*; 
import javax.naming.directory.*; 
import java.util.*; 
import java.sql.*; 

public class LDAPTEST { 

    public static void main(String args[]) { 

     String lcf    = "com.sun.jndi.ldap.LdapCtxFactory"; 
     String ldapurl   = "ldaps://ldap-cit.smew.acme.com:636/o=acme.com"; 
     String loginid   = "George.Jetson"; 
     String password   = ""; 
     DirContext ctx   = null; 
     Hashtable env    = new Hashtable(); 
     Attributes attr   = null; 
     Attributes resultsAttrs = null; 
     SearchResult result  = null; 
     NamingEnumeration results = null; 
     int iResults    = 0; 
     int iAttributes   = 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()); 
        iAttributes++; 


       }// end for loop 

       iResults++; 
      }// end while loop 

      System.out.println("Records == " + iResults + " Attributes: " + iAttributes); 

     }// end try 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 



    }// end function main() 
}// end class LDAPTEST 

Respuesta

18

Por desgracia, la autenticación con un DN y una contraseña vacía es una de las difficiency de LDAP, y da como resultado una respuesta positiva "autenticado" desde el servidor. Algunos servidores LDAP tienen opciones de configuración para deshabilitar ese comportamiento que se desaconsejó en la última revisión de LDAPv3 (RFC 4511), e incluso lo tienen deshabilitado de forma predeterminada.

En última instancia, la aplicación del cliente debe verificar los parámetros de entrada y asegurarse de que la contraseña no esté vacía.

Saludos cordiales,

Ludovic

+0

Gracias, me dijiste lo que quería saber: si podía o debía hacer algo más allá de mantener una estricta validación de los datos de las contraseñas enviadas. Intenté cambiar a "fuerte" y "SASL" con el código anterior solo para obtener un mensaje de excepción que dijera que el tipo de autenticación no era compatible (¿por el servidor?). Entonces, dado que el servidor no admite nada más, tuve la libertad de seguir adelante. – Steve

8

Es necesario cambiar el método de autenticación de ser simple (que es no algo para usar en un entorno de producción de todos modos, al menos no sin SSL).

Como se dice aquí: http://docs.oracle.com/javase/jndi/tutorial/ldap/security/simple.html

Si pasa una cadena vacía, una matriz de bytes/char vacío o nulo a la propiedad Context.SECURITY_CREDENTIALS medio ambiente, entonces el mecanismo de autenticación habrá "ninguna" . Esto se debe a que LDAP requiere que la contraseña sea no vacía para autenticación simple. El protocolo convierte automáticamente la autenticación a "ninguno" si no se proporciona una contraseña.

+0

¿es suficiente para cambiar env.put (Context.SECURITY_AUTHENTICATION, "simple"); a env.put (Context.SECURITY_AUTHENTICATION, "strong");? ¿Podría eso tener efectos secundarios no deseados? ¿Solo se trata de aceptar/rechazar contraseñas en blanco o afectará a otras cosas? – Steve

+0

No estoy seguro, usamos algunas clases de Novell para conectarnos a ldap, y no dice nada sobre este valor. Probablemente deberías leer sobre los diferentes métodos de autenticación, probablemente deberías comenzar aquí: http://docs.oracle.com/javase/tutorial/jndi/ldap/authentication.html – Tobb

+0

Estoy votando esto como el segundo más útil comentar en este hilo Muchas gracias. – Steve

1

Lo que sucede cuando se envía una contraseña "vacía" es que la autenticación (es decir, el enlace) se realiza como anónimo.

Su código podría modificarse para detectar una contraseña o ID de usuario vacíos para detener esta actividad.

Algunas implementaciones de LDAP pueden detener cualquier enlace anónimo.

3

Hay dos tipos de operaciones BIND, simple y SASL. En el caso del enlace simple, hay cuatro posibilidades:

  • vacío DN y la contraseña vacío: anonymous, no tiene lugar la autenticación. Este es el estado inicial, y también el estado cuando una solicitud BIND es recibida por el servidor
  • no vacío DN, contraseña vacía: unauthenticated, sin autentificación tiene lugar
  • no vacío DN, no emptypassword: la normalidad caso, se intenta autenticar
  • DN vacío, contraseña no vacía: el comportamiento del servidor no está definido en los estándares LDAP. No hay autenticación.

Cuando se establece inicialmente una conexión, la conexión es anonymous.Cada solicitud BIND restablece el estado de la conexión al anonymous. Cada solicitud BIND correcta cambia el estado de autorización de la conexión a la del nombre completo. Cada solicitud BIND sin éxito deja la conexión sin autenticar.

La semántica de BIND se definen en LDAP: Authentication

Cuestiones relacionadas