JavaでLDAPS(LDAP over SSL/TLS)をやりたくて実験プログラムを作ったところ、以下のようなエラーに遭遇しました。
Lookup failed: javax.naming.CommunicationException: simple bind failed: Samba4サーバ:636 [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]
結果からの推測ですが、デフォルトのキーストア(jre/lib/security/cacrts)であってもVM引数かJAVA_OPTSで指定する必要があるようです。
以下、参考までに実験プログラムとキーストアにサーバ証明書(公開鍵)を登録する方法を記しておきます。
##実験プログラム
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class App {
public static void main(String args[]) {
final String username = "user3";
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, username + "@devel.local");
env.put(Context.SECURITY_CREDENTIALS, "User3###");
env.put(Context.PROVIDER_URL, "ldaps://Samba4サーバ:636");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PROTOCOL, "ssl");
DirContext ctx;
try {
ctx = new InitialDirContext(env);
Attributes attrs = ctx
.getAttributes("CN=user3,CN=Users,DC=devel,DC=local");
if (attrs != null) {
try {
for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();) {
Attribute attr = (Attribute) ae.next();
System.out.println("attribute: " + attr.getID());
for (NamingEnumeration e = attr.getAll(); e.hasMore();
System.out.println("value: " + e.next()));
}
} catch (NamingException e) {
e.printStackTrace();
}
}
ctx.close();
} catch (AuthenticationException e) {
System.out.println("Invalid credentials");
} catch (NamingException e) {
System.out.println("Lookup failed: " + e);
}
}
}
##キーストアにサーバの自己証明書を登録する方法
###サーバの自己証明書を作成する(サーバ)
末尾に示す「Samba4のための自己証明書の作成方法」を参考にして、サーバの自己証明書を作成します。そのファイルはmyCert.pemとします。
###サーバの自己証明書をキーストアに登録する(クライアント)
サーバで作ったmyCert.pemを%JAVA_HOME%\jre\lib\securityにコピーした後、以下のコマンドでインポートします。
cd %JAVA_HOME%\jre\lib\security
keytool -keystore cacerts -importcert -alias surnet-samba-ad -file myCert.pem
エリアスに指定した名前(surnet-samba-ad)は何でもいいと思います。キーストアはデフォルトのキーストアを指定しましたが、新しく作ってもいいと思います。
###実験プログラムを実行する
実験プログラムを実行する前に、JAVA_OPTSにキーストアを指定しておきます。
set JAVA_OPTS="-Djavax.net.ssl.trustStore=%JAVA_HOME%\jre\lib\security\cacerts -Djavax.net.ssl.trustStorePassword=changeit"
##参考