2012-08-28 18 views
8

No puedo autenticar a un usuario que usa LDAP. Tengo siguientes detalles:LDAP: cómo autenticar al usuario con los detalles de la conexión

URL=ldap://10.10.10.10:389 
LDAP BASE:DC=lab2,DC=ins 
LDAP Bind Account: CN=Ldap Bind,OU=Service Accounts,OU=TECH,DC=lab2,DC=ins 
LDAP Bind Account Pw: secret 

que puede buscar un valor sAMAccountName usando detalles anteriores, pero la forma de autenticar a un usuario con el nombre de usuario y contraseña?
Si sigue mis preguntas anteriores, entenderá que puedo conectarme con el servidor LDAP pero no puedo autenticarlo.
usuario que autenticar:

user: someusername 
password: somepwd 

no soy capaz de conectar con el servidor LDAP con 'somepwd' y cómo debo usar someusername. Puedo buscar un usuario dado como sAMAccountName.

+1

¿tiene la contraseña correcta? funciona con un cliente como JXplorer? – dbrin

+0

@DmitryB Puedo conectarme al servidor con 'secreto' pero no con 'somepwd'. –

+0

contraseña incorrecta que :) – dbrin

Respuesta

22

Este es un mashup de cosas que he encontrado en varios lugares. Debería guiarte por la ruta correcta si no quieres utilizar el SDK de UnboundID. Esto no es calidad de producción, es posible que desee agregar el material SSL aquí si su tienda lo admite.

public static Boolean validateLogin(String userName, String userPassword) { 
    Hashtable<String, String> env = new Hashtable<String, String>(); 


    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
    env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN); 

    // To get rid of the PartialResultException when using Active Directory 
    env.put(Context.REFERRAL, "follow"); 

    // Needed for the Bind (User Authorized to Query the LDAP server) 
    env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
    env.put(Context.SECURITY_PRINCIPAL, LDAP_BIND_DN); 
    env.put(Context.SECURITY_CREDENTIALS, LDAP_BIND_PASSWORD); 

    DirContext ctx; 
    try { 
     ctx = new InitialDirContext(env); 
    } catch (NamingException e) { 
     throw new RuntimeException(e); 
    } 

    NamingEnumeration<SearchResult> results = null; 

    try { 
     SearchControls controls = new SearchControls(); 
     controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Search Entire Subtree 
     controls.setCountLimit(1); //Sets the maximum number of entries to be returned as a result of the search 
     controls.setTimeLimit(5000); // Sets the time limit of these SearchControls in milliseconds 

     String searchString = "(&(objectCategory=user)(sAMAccountName=" + userName + "))"; 

     results = ctx.search("", searchString, controls); 

     if (results.hasMore()) { 

      SearchResult result = (SearchResult) results.next(); 
      Attributes attrs = result.getAttributes(); 
      Attribute dnAttr = attrs.get("distinguishedName"); 
      String dn = (String) dnAttr.get(); 

      // User Exists, Validate the Password 

      env.put(Context.SECURITY_PRINCIPAL, dn); 
      env.put(Context.SECURITY_CREDENTIALS, userPassword); 

      new InitialDirContext(env); // Exception will be thrown on Invalid case 
      return true; 
     } 
     else 
      return false; 

    } catch (AuthenticationException e) { // Invalid Login 

     return false; 
    } catch (NameNotFoundException e) { // The base context was not found. 

     return false; 
    } catch (SizeLimitExceededException e) { 
     throw new RuntimeException("LDAP Query Limit Exceeded, adjust the query to bring back less records", e); 
    } catch (NamingException e) { 
     throw new RuntimeException(e); 
    } finally { 

     if (results != null) { 
      try { results.close(); } catch (Exception e) { /* Do Nothing */ } 
     } 

     if (ctx != null) { 
      try { ctx.close(); } catch (Exception e) { /* Do Nothing */ } 
     } 
    } 
} 
+2

esta es la mejor solución que he visto hasta ahora, buscaba específicamente autenticar a un usuario después de enlazarlo al servidor LDAP. – likeToCode

+0

¿Esto es seguro de usar con la agrupación de conexiones? – bdrx

7

Una conexión LDAP comienza como anonymous. Para cambiar el estado de autorización de una conexión, use la solicitud BIND. La solicitud BIND toma dos formas, 'simple' o 'SASL'. La solicitud 'simple' BIND toma un nombre distinguido y contraseña. La solicitud BIND debe transmitirse a través de una conexión segura, o una conexión no segura promovida a una conexión segura utilizando la solicitud extendida StartTLS.

Utilizando el SDK de LDAP UnboundID:

// exception handling not shown 
LDAPConnection ldapConnection = new LDAPConnection(hostname,port); 
BindRequest bindRequest = new SimpleBindRequest(username,password); 
BindResult bindResult = ldapConnection.bind(bindRequest); 
if(bindResult.getResultCode().equals(ResultCode.SUCCESS)) { 
    /// successful authentication 
} 
ldapConnection.close(); 
+0

No puedo usar UnboundID LDAP SDK debido a las restricciones del cliente. ¿Hay alguna otra forma de lograrlo? –

Cuestiones relacionadas