有没有办法与ldaps连接并忽略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.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:无法找到到所请求目标的有效认证路径]

有人知道我该如何解决这个问题?

多谢建议

解决方法

我不知道您的环境,但是您可以添加我不知道您的环境,但是可以将已发布che LDAP证书的CA证书添加到系统的受信任CA中吗?

通过这种方式,可以增强应用程序的安全性,否则使用LDAP几乎没有用。

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

如果该应用程序安装在域的计算机上,则可以共享CA证书引发组策略规则。您可以看到the Microsoft documentation。域中的每个证书必须由受信任的CA发行。

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

,

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

如果您的证书很好。您所有的客户端(Web浏览器或移动SO)都可以使用您的应用程序。

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

,

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

,

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

https://stackoverflow.com/a/4615497/88122

找到了两者的示例

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...