2014-11-13 5 views
0

*LDAP 오류 49

내가 자바 LDAP 연결 문제와 stucked 일을 해요 * 전액 작업 솔루션과 답변 아래 글.

는 LDAP 서버에 연결하는 나의 방법 :

public boolean authenticate(String user, String password) { 
    StringBuilder url = new StringBuilder("ldap://"); 
    url.append("10.0.0.1"); 
    url.append(":"); 
    url.append(389); 

    StringBuilder securityPrincipal = new StringBuilder("uid="); 
    securityPrincipal.append(user); 
    securityPrincipal.append(","); 
    securityPrincipal.append("dc=XXXXX,dc=YYY,dc=ZZ"); 

    Hashtable<String, String> env; 
    env = new Hashtable<String, String>(); 
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
    env.put(Context.PROVIDER_URL, url.toString()); 
    env.put(Context.SECURITY_AUTHENTICATION, "simple"); 
    env.put(Context.SECURITY_PRINCIPAL, securityPrincipal.toString()); 

    env.put(Context.SECURITY_CREDENTIALS, password); 

    System.out.println(url); 
    System.out.println(securityPrincipal.toString()); 

    try { 
     ldap = new InitialLdapContext(env, null); 
    } catch (NamingException e) { 
     e.printStackTrace(); 
     return false; 
    } 

    return true; 
} 

보안 및 공개 이유로, 나는 XXXXX, YYY와 ZZ는 "직류"ommited 및 LDAP 서버의 IP를 변경했습니다.

나는 PHP 소프트웨어 (GLPI)에 동일한 조합을 사용했으며 매력처럼 작동했습니다.

javax.naming.AuthenticationException: [LDAP: error code 49 - Invalid Credentials] 
    at com.sun.jndi.ldap.LdapCtx.mapErrorCode(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 
    at com.sun.jndi.ldap.LdapCtx.processReturnCode(Unknown Source) 

전체 DN은 이것이다 : 그러나, 하나님을 위하여, 자바는 항상이 오류가 나에게주는이 LDAP configurarion을 받아 들일 수 없다

변수 사용자가 "tiagoadami"변수 "인수"로 가득

uid=tiagoadami,dc=XXXXX,dc=YYY,dc=ZZ 
일반 텍스트 암호로 채워집니다.

이것은 매우 성가신 일입니다. 내 암호가 정확하며 사용자 이름이 "tiagoadami"인 모든 응용 프로그램과 암호로 인증됩니다. 나는 지금 옵션이 없어. 누구든지 나를 도울 수 있습니까?

+0

디렉토리, OpenLdap.)? – BillFromHawaii

+0

사용자의 DN이 uid와 dc 사이의 개체 유형이 누락되었습니다. – BillFromHawaii

+0

리눅스를 실행하는 OpenLdap 3입니다. 문제는 다음과 같습니다. 익명 로그인은 괜찮습니다. - 보안 오류로 인한 희망 -이 DN이 내 사용자에게 맞는지 알 수있을 때 익명으로 모든 LDAP 트리를 가져올 수 있습니다. 이 동일한 DN을 GLPI로 설정하면 완벽하게 작동합니다. LdapExplorerTool2라는 Windows 도구로이 DN을 시도했지만 작동하지 않습니다. 내가 뭘 놓치고 있니? – adamitj

답변

-1

나는 모든 사람들의 도움을 받아서 기쁩니다. 당신의 도움이 없었다면 나는 아직 갇혀있을 것입니다. 나는 LDAP 서버가 기본 DN만으로 바인드를 허용하지 않는다는 것을 알아 냈습니다. I이었다이 두 클래스와

uid=tiagoadami,dc=XXXXX,dc=YYY,dc=ZZ 

Sooooooooo looooooooong ... :

uid=tiagoadami,ou=proto,ou=serv,ou=user,ou=collab,ou=all,dc=XXXXX,dc=YYY,dc=ZZ 

대신 :

는 필사적으로 노력 후, 나는 나무의 전체 경로를 사용하여 연결 수 해결할 수 모두 내 LDAP 문제. 나는 그들을 트리 내부를 검색하고 주어진 UID에 대해 전체 DN을 얻도록 변경했습니다. 여기에서 그들은 같은 문제를 가진 사람을 위해 다음과 같습니다

TrustAllCertificatesSSLSocketFactory.java

package com.adamiworks.commonutils.ldap; 

import java.io.IOException; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.security.SecureRandom; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

import javax.net.SocketFactory; 
import javax.net.ssl.SSLContext; 
import javax.net.ssl.TrustManager; 
import javax.net.ssl.X509TrustManager; 

/** 
* This class accept all SSL Certificates even if it can assure its 
* Certification Institute. 
* 
* DO NOT USE AT PRODUCTION ENVIRONMENTS 
* 
* @author Tiago J. Adami 
* 
*/ 
public class TrustAllCertificatesSSLSocketFactory extends SocketFactory { 
    private SocketFactory socketFactory; 

    public TrustAllCertificatesSSLSocketFactory() { 
     try { 
      SSLContext ctx = SSLContext.getInstance("SSL"); 
      ctx.init(null, new TrustManager[] { new AllCertificatesTrustManager() }, new SecureRandom()); 
      socketFactory = ctx.getSocketFactory(); 
     } catch (Exception ex) { 
      ex.printStackTrace(System.err); /* handle exception */ 
     } 
    } 

    public static SocketFactory getDefault() { 
     return new TrustAllCertificatesSSLSocketFactory(); 
    } 

    @Override 
    public Socket createSocket(String string, int i) throws IOException, UnknownHostException { 
     return socketFactory.createSocket(string, i); 
    } 

    @Override 
    public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException, UnknownHostException { 
     return socketFactory.createSocket(string, i, ia, i1); 
    } 

    @Override 
    public Socket createSocket(InetAddress ia, int i) throws IOException { 
     return socketFactory.createSocket(ia, i); 
    } 

    @Override 
    public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException { 
     return socketFactory.createSocket(ia, i, ia1, i1); 
    } 

    private class AllCertificatesTrustManager implements X509TrustManager { 
     public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
      // do nothing 
     } 

     public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { 
      // do nothing 
     } 

     public X509Certificate[] getAcceptedIssuers() { 
      return new java.security.cert.X509Certificate[0]; 
     } 
    } 
} 

LdapUtils.java이 (액티브이다 LDAP 서버의 어떤 종류의

package com.adamiworks.commonutils.ldap; 

import java.util.Hashtable; 
import java.util.Properties; 

import javax.naming.AuthenticationException; 
import javax.naming.Context; 
import javax.naming.NamingEnumeration; 
import javax.naming.NamingException; 
import javax.naming.directory.Attributes; 
import javax.naming.directory.DirContext; 
import javax.naming.directory.InitialDirContext; 
import javax.naming.directory.SearchControls; 
import javax.naming.directory.SearchResult; 

/** 
* Authenticates with LDAP Servers. Just using a single UID this class goes deep 
* inside the user's tree and find the full DN for the given UID. It also allows 
* to connect to servers when you don't have the certificate yet... but use this 
* feature at your own risk! 
* 
* @author Tiago J. Adami 
* 
*/ 
public class LdapUtils { 
    private InitialDirContext ldap; 
    private String host; 
    private int port; 
    private boolean useSSL; 
    private boolean ignoreCertificates; 
    private String basedn; 

    public InitialDirContext getLdap() { 
     return ldap; 
    } 

    public boolean isIgnoreCertificates() { 
     return ignoreCertificates; 
    } 

    public void setIgnoreCertificates(boolean ignoreCertificates) { 
     this.ignoreCertificates = ignoreCertificates; 
    } 

    public String getHost() { 
     return host; 
    } 

    public int getPort() { 
     return port; 
    } 

    public String getBasedn() { 
     return basedn; 
    } 

    public boolean isUseSSL() { 
     return useSSL; 
    } 

    public void setUseSSL(boolean useSSL) { 
     this.useSSL = useSSL; 
    } 

    /** 
    * Default constructor 
    * 
    * @param host 
    * @param port 
    * @param basedn 
    * @param useSSL 
    * @param ignoreCertificates 
    */ 
    public LdapUtils(String host, int port, String basedn, boolean useSSL, boolean ignoreCertificates) { 
     super(); 
     this.host = host; 
     this.port = port; 
     this.useSSL = useSSL; 
     this.basedn = basedn; 
     this.ignoreCertificates = ignoreCertificates; 
    } 

    /** 
    * Authenticates an user and password from LDAP credentials; 
    * 
    * @param uid 
    * @param password 
    * @return 
    * @throws NamingException 
    */ 
    public boolean authenticate(String uid, String password) { 
     try { 
      String url = getUrl(); 
      String dn = this.getDnByUid(uid); 

      Properties env = new Properties(); 
      env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
      env.put(Context.PROVIDER_URL, url); 

      env.put(Context.SECURITY_AUTHENTICATION, "simple"); 

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

      if (this.useSSL) { 
       env.put(Context.SECURITY_PROTOCOL, "ssl"); 
      } 

      if (this.useSSL && this.ignoreCertificates) { 
       env.put("java.naming.ldap.factory.socket", "com.adamiworks.commonutils.ldap.TrustAllCertificatesSSLSocketFactory"); 
      } 

      ldap = new InitialDirContext(env); 
     } catch (AuthenticationException e) { 
      e.printStackTrace(); 
      return false; 
     } catch (NamingException e) { 
      e.printStackTrace(); 
      return false; 
     } 

     return true; 
    } 

    /** 
    * Returns the url based on SSL or not 
    * 
    * @return 
    */ 
    private String getUrl() { 
     StringBuilder url = new StringBuilder(); 

     url.append(this.useSSL ? "ldaps://" : "ldap://"); 
     url.append(host); 
     url.append(":"); 
     url.append(port); 
     return url.toString(); 
    } 

    /** 
    * Returns the url based on SSL or not 
    * 
    * @return 
    */ 
    private String getUrlWithoutSsl() { 
     StringBuilder url = new StringBuilder(); 
     url.append("ldap://"); 
     url.append(host); 
     return url.toString(); 
    } 

    /** 
    * Return LDAP authentication modes allowed by the server 
    * 
    * @param url 
    * @return 
    * @throws NamingException 
    */ 
    public Attributes getLdapAuths() throws NamingException { 

     // Create initial context 
     DirContext ctx = new InitialDirContext(); 

     // Read supportedSASLMechanisms from root DSE 
     Attributes attrs = ctx.getAttributes(this.getUrl(), new String[] { "supportedSASLMechanisms" }); 

     System.out.println(attrs); 

     return attrs; 

    } 

    /** 
    * Returns the full DN (distinct name) for a given UID 
    * 
    * @param uid 
    *   the UID name of the user 
    * @return full tree path of LDAP 
    * @throws NamingException 
    */ 
    @SuppressWarnings("rawtypes") 
    public String getDnByUid(String uid) throws NamingException { 
     String url = this.getUrlWithoutSsl() + "/" + this.basedn; 

     Hashtable<String, Object> env = new Hashtable<String, Object>(11); 
     env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 
     env.put(Context.PROVIDER_URL, url); 

     String ret = "uid=" + uid; 
     DirContext ctx = null; 

     try { 
      // Create initial context 
      ctx = new InitialDirContext(env); 

      SearchControls controls = new SearchControls(); 
      controls.setSearchScope(SearchControls.SUBTREE_SCOPE); 

      NamingEnumeration answer = ctx.search("", "(uid=" + uid + ")", controls); 

      while (answer.hasMore()) { 
       SearchResult sr = (SearchResult) answer.next(); 
       ret = sr.getNameInNamespace(); 
       break; 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      // Close the context when we're done 
      ctx.close(); 
     } 

     System.out.println("FULL DN: " + ret); 

     return ret; 
    } 

} 
관련 문제