简体   繁体   English

有没有办法连接ldaps并忽略java中的证书?

[英]is there a way to connect with ldaps and ignore certificates in java?

I have an application java on tomcat with ldap and I can authenticate without problem.我在带有 ldap 的 tomcat 上有一个应用程序 java,我可以毫无问题地进行身份验证。 Now, my company would to insert ssl layer on ldap, so I need to use ldaps.现在,我的公司要在 ldap 上插入 ssl 层,所以我需要使用 ldaps。 Any suggestion to ignore certificate and trust certificate from ldaps server?有什么建议可以忽略来自 ldaps 服务器的证书和信任证书吗?

This is my code that works for ldap这是我适用于 ldap 的代码

final String ldapAdServer = "ldap://my_ldap_url:3268";
final String ldapSearchBase = "Ldap_search_base";

//need a default user to be able to do query on AD
final String ldapUsername = "username_path_AD";
final String ldapPassword = "password_path_AD";


Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.SECURITY_AUTHENTICATION, "simple");
if(ldapUsername != null) {
    env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
}
if(ldapPassword != null) {
    env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
}
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapAdServer);

//ensures that objectSID attribute values
//will be returned as a byte[] instead of a String
env.put("java.naming.ldap.attributes.binary", "objectSID");

LdapContext ctx = new InitialLdapContext(env,null);

return ctx;

now, I tried to create this class to trust all certificates :现在,我尝试创建这个类来信任所有证书:

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class SSLFix {
 
 public static void execute(){
  TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
           return null;
          }
          @Override
          public void checkClientTrusted(X509Certificate[] arg0, String arg1)
           throws CertificateException {}
 
          @Override
          public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {}

          }
     };

  SSLContext sc=null;
  try {
   sc = SSLContext.getInstance("SSL");
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
  try {
   sc.init(null, trustAllCerts, new java.security.SecureRandom());
  } catch (KeyManagementException e) {
   e.printStackTrace();
  }
  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

  // Create all-trusting host name verifier
  HostnameVerifier validHosts = new HostnameVerifier() {
  @Override
  public boolean verify(String arg0, SSLSession arg1) {
   return true;
  }
  };
  // All hosts will be valid
  HttpsURLConnection.setDefaultHostnameVerifier(validHosts);
 }

}

and so I decided to change my previous ldap code with this:所以我决定用这个来改变我以前的 ldap 代码:

public LdapContext getLDAPContext() throws NamingException
{
    SSLFix.execute();
    
    
    final String ldapAdServer = "ldaps://my_ldap_url:3269";
    final String ldapSearchBase = "ldap_search_base";
    
//need a default user to be able to do query on AD
    final String ldapUsername = "username_path_AD";
    final String ldapPassword = "password_path_AD";
    
    
    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    if(ldapUsername != null) {
        env.put(Context.SECURITY_PRINCIPAL, ldapUsername);
    }
    if(ldapPassword != null) {
        env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
    }
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, ldapAdServer);

    //ensures that objectSID attribute values
    //will be returned as a byte[] instead of a String
    env.put("java.naming.ldap.attributes.binary", "objectSID");
    
    LdapContext ctx = new InitialLdapContext(env,null);
    
    return ctx;
}

but when I execute the control for ldaps, I obtain this error:但是当我执行 ldaps 的控制时,我得到了这个错误:

javax.naming.CommunicationException: simple bind failed: [Root exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target] javax.naming.CommunicationException:简单绑定失败:[Root 异常是 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到有效的证书请求目标的路径]

You must import the "LDAP-CA certificate" into your Java virtual machine.您必须将“LDAP-CA 证书”导入 Java 虚拟机。
To do this, you can run:为此,您可以运行:
keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias ldap-CA -import -file ldap-ca-crt.pem keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias ldap-CA -import -file ldap-ca-crt.pem

If your certificate is good.如果你的证书是好的。 All your clients (web browsers or mobile SO) will have no problem using your application.您的所有客户端(Web 浏览器或移动 SO)在使用您的应用程序时都没有问题。

Don't forget to import your intermediate certificates or chained certificates.(these certificates usually come together with LDAP-CA certificate)不要忘记导入您的中间证书或链式证书。(这些证书通常与 LDAP-CA 证书一起提供)

I don't know your environment, but can you add theI don't know your environment, but can you add the CA certificate that has released che LDAP certificate to your system's trusted CAs?我不知道你的环境,但你能补充一下我不知道你的环境,但是你能把已经发布che LDAP证书的CA证书添加到你系统的可信CA中吗?

In this way, you enhance the app security, otherwise is almost useless to use LDAPs.这样,您增强了应用程序的安全性,否则使用 LDAP 几乎毫无用处。

I suppose that the Domain Controller has a CA server installed and the LDAP's certificate is released by it.我想域控制器安装了一个CA 服务器并且 LDAP 的证书是由它发布的。 Download this certificate and add it to you environment.下载此证书并将其添加到您的环境中。

If the app is installed on domain's computers, you can share the CA certificate throw a group policy rule.如果应用程序安装在域的计算机上,您可以共享 CA 证书并抛出组策略规则。 You can see the Microsoft documentation .您可以查看Microsoft 文档 Each certificate in a domain must be released by a trusted CA.域中的每个证书都必须由受信任的 CA 发布。

If you can't accept this certificate use the option 2 from this answer .如果您不能接受此证书,请使用此答案中的选项 2。

thanks all for your response.感谢大家的回应。 I decided to create X509TrustManager and SSLSocketFactory, and so allow all certificates.我决定创建 X509TrustManager 和 SSLSocketFactory,因此允许所有证书。 I solved my issue in this way我以这种方式解决了我的问题

You can create a custom X509TrustManager or SSLSocketFactory.您可以创建自定义 X509TrustManager 或 SSLSocketFactory。

Found examples of both at https://stackoverflow.com/a/4615497/88122https://stackoverflow.com/a/4615497/88122 上找到了两者的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM