繁体   English   中英

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

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

我在带有 ldap 的 tomcat 上有一个应用程序 java,我可以毫无问题地进行身份验证。 现在,我的公司要在 ldap 上插入 ssl 层,所以我需要使用 ldaps。 有什么建议可以忽略来自 ldaps 服务器的证书和信任证书吗?

这是我适用于 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;

现在,我尝试创建这个类来信任所有证书:

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);
 }

}

所以我决定用这个来改变我以前的 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;
}

但是当我执行 ldaps 的控制时,我得到了这个错误:

javax.naming.CommunicationException:简单绑定失败:[Root 异常是 javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到有效的证书请求目标的路径]

您必须将“LDAP-CA 证书”导入 Java 虚拟机。
为此,您可以运行:
keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias ldap-CA -import -file ldap-ca-crt.pem

如果你的证书是好的。 您的所有客户端(Web 浏览器或移动 SO)在使用您的应用程序时都没有问题。

不要忘记导入您的中间证书或链式证书。(这些证书通常与 LDAP-CA 证书一起提供)

我不知道你的环境,但你能补充一下我不知道你的环境,但是你能把已经发布che LDAP证书的CA证书添加到你系统的可信CA中吗?

这样,您增强了应用程序的安全性,否则使用 LDAP 几乎毫无用处。

我想域控制器安装了一个CA 服务器并且 LDAP 的证书是由它发布的。 下载此证书并将其添加到您的环境中。

如果应用程序安装在域的计算机上,您可以共享 CA 证书并抛出组策略规则。 您可以查看Microsoft 文档 域中的每个证书都必须由受信任的 CA 发布。

如果您不能接受此证书,请使用此答案中的选项 2。

感谢大家的回应。 我决定创建 X509TrustManager 和 SSLSocketFactory,因此允许所有证书。 我以这种方式解决了我的问题

您可以创建自定义 X509TrustManager 或 SSLSocketFactory。

https://stackoverflow.com/a/4615497/88122 上找到了两者的例子

暂无
暂无

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

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