JNDIを使ってInterstage ディレクトリサービスへアクセスするためには、セションをオープンして、初期設定とユーザ認証を行う必要があります。
セションのオープン
セションをオープンするには、以下のクラスを使用して、初期コンテキストを作成します。
javax.naming.InitialContext
初期設定、ユーザ認証
初期コンテキストの生成時に、環境プロパティを使って、以下の情報を設定します。
LDAPサービスプロバイダ
接続先のリポジトリ(ホスト名、ポート番号)
認証方法
リポジトリへバインドするときのユーザDN
リポジトリへバインドするときのユーザDNのパスワード
LDAPサービスプロバイダ
環境プロパティ「javax.naming.Context.INITIAL_CONTEXT_FACTORY」に以下の値を指定します。
「"com.sun.jndi.ldap.LdapCtxFactory"」
接続先のリポジトリ(ホスト名、ポート番号)
環境プロパティ「javax.naming.Context.PROVIDER_URL」にリポジトリのURL情報を以下の形式で指定します。
「"ldap://ホスト名:ポート番号"」
IPv6アドレスを指定する場合は、「[」、「]」(角括弧)で囲みます。
「"ldap://[IPv6アドレス]:ポート番号"」
JavaでのIPv6の使用の詳細は、Sun Microsystems, Inc.から提供されているJDKのドキュメントを参照してください。
認証方法
環境プロパティ「javax.naming.Context.SECURITY_AUTHENTICATION」にリポジトリへバインドする際に使用する認証方法を指定します。値に「"none"」または「"simple"」を指定してください。
"none" : アノニマス(匿名ユーザ)認証
"simple" : 簡易認証
リポジトリへバインドするユーザDN
環境プロパティ「javax.naming.Context.SECURITY_PRINCIPAL」にリポジトリへバインドするユーザのDNを指定します。省略値はアノニマス(匿名ユーザ)です。
リポジトリへバインドするユーザDNのパスワード
環境プロパティ「javax.naming.Context.SECURITY_CREDENTIALS」にリポジトリへバインドするユーザDNのパスワードを指定します。省略値はパスワードなしです。
以下に、初期コンテキストの作成例を示します。
Hashtable<String, Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://localhost:389"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=User001, ou=interstage, o=fujitsu,dc=com"); env.put(Context.SECURITY_CREDENTIALS, "mypassword"); DirContext ctx = new InitialDirContext(env);
Interstage ディレクトリサービスへのアクセスを終了した後にセションのクローズをする必要があります。
SSL通信を使用する
接続先のリポジトリのURL情報を、SSL通信を使用しないときとは違い、「ldap」スキームではなく、「ldaps」スキームを使用します。
接続先のリポジトリ(ホスト名、ポート番号)
環境プロパティ「javax.naming.Context.PROVIDER_URL」にリポジトリのURL情報を以下の形式で指定します。ポート番号にはSSL通信で使用するポート番号を指定します。
「"ldaps://ホスト名:ポート番号"」
SSL通信を使用するときは、“初期設定、ユーザ認証”の環境プロパティに加えて、以下の環境プロパティおよびシステムプロパティを指定します。
セキュリティプロトコル
環境プロパティ「javax.naming.Context.SECURITY_PROTOCOL」にセキュリティプロトコルを指定します。
「"ssl"」を指定してください。
ソケットファクトリ
環境プロパティ「java.naming.ldap.factory.socket」にソケットファクトリのクラス名を指定します。この環境プロパティを省略すると、SSLは使用されません。以下の値を指定してください。
「"com.fujitsu.ssl.FjSSLSocketFactory"」
SSL環境定義ファイル
システムプロパティ「user.sslenvfile」にSSL環境定義ファイルを指定します。値にSSL環境定義ファイルの絶対パスを指定してください。SSL環境定義ファイルの作成方法は、“4.2.4 SSL環境定義ファイルの設定(クライアント)”を参照してください。
SSLログファイル出力先
システムプロパティ「user.ssllogdir」にSSLログファイル出力先のディレクトリを指定します。SSL通信時、SSLログファイルディレクトリには、SSLライブラリが出力するログファイルが格納されます。SSL使用時、SSLのログを採取する場合に指定します。
以下に、SSL通信を使用するときの、初期コンテキストの作成例を示します。
Hashtable<String, Object> env = new Hashtable<String, Object>(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldaps://localhost:636"); env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, "cn=User001, ou=interstage, o=fujitsu,dc=com"); env.put(Context.SECURITY_CREDENTIALS, "mypassowrd"); /* SSL用の環境プロパティの設定 */ env.put("java.naming.ldap.factory.socket", "com.fujitsu.ssl.FjSSLSocketFactory"); env.put(Context.SECURITY_PROTOCOL, "ssl" ); /* システムプロパティの取得 */ Properties prop = System.getProperties(); prop.put("user.sslenvfile", sslenvfile); prop.put("user.ssllogdir", ssllogdir ); DirContext ctx = new InitialDirContext(env);
SSLエラーを取得する
SSLに関するエラーを取得する方法について説明します。
SSLから出力されるメッセージからエラータイプ、エラーコードを取得します。
出力されるメッセージから、“FjSSLSocket”をキーにしてエラー情報を取り出します。
エラー情報から、“errtype=”をキーにしてエラータイプを取り出します。
エラー情報から、“SSLLerrorcode=”をキーにしてSSLエラーコードを取り出します。
メッセージ例
com.fujitsu.ssl.SSLException: FjSSLSocket:SSL_Init error, errtype=10 SSLLerrorcode=10004c
エラータイプ、SSLエラーコードは以下の方法で取得できます。
catch(NamingException ne){ Throwable msg = ne.getRootCause(); String msgStr = null; int ssl_error = -1; if ( msg != null ){ /* エラーメッセージの取得 */ msgStr = msg.toString(); /* エラーを取得するキー検索 (1) */ ssl_error = msgStr.indexOf("FjSSLSocket"); } /* SSLのときの処理 */ if ( ssl_error != -1 ){ int index1 = msgStr.indexOf("errtype="); int index2 = msgStr.indexOf("SSLLerrorcode="); if ( index1 != -1 ){ /* エラータイプの取得 (2) */ String error = msgStr.substring(index1 + "errtype=".length(), index1 + "errtype=".length() + 2); /* エラータイプの表示 */ System.out.println("SSL Error type : " + error); } if ( index2 != -1 ){ /* SSLエラーコードの取得 (3) */ String error = msgStr.substring(index2 + "SSLLerrorcode=".length()); /* SSLエラーコードの表示 */ System.out.println("SSL Error code : " + error); } } }
SSLExceptionのエラータイプ、エラーコードの値と対処については、“メッセージ集”の“Interstage ディレクトリサービスから通知されるエラーコード”-“SSLExceptionのエラータイプ”、および“SSLエラーコード”を参照してください。
javax.naming.directory.InitialDirContextクラスは、セションのオープンと同時に初期設定、ユーザ認証を行います。したがって、処理中にユーザ認証情報の変更などを行う場合は、新規にセションをオープンする必要があります。この場合、オープンしているセション数だけセションのクローズを行う必要があります。
また、javax.naming.ldap.InitialLdapContextクラスを利用することによって、セションのオープン中に、ユーザ認証などの変更を行うことができます。指定方法については、以下を参考にしてください。
...... Hashtable env = new Hashtable(5, 0.75f); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); env.put(Context.PROVIDER_URL, "ldap://host:389"); // アノニマス(匿名ユーザ)認証でセションをオープン env.put(Context.SECURITY_AUTHENTICATION, "simple"); env.put(Context.SECURITY_PRINCIPAL, ""); env.put(Context.SECURITY_CREDENTIALS, ""); InitialLdapContext ctx = new InitialLdapContext(env,null); ...... // 管理者権限で再認証 ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple"); ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, "cn=admin,ou=interstage,o=fujitsu,dc=com"); ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, "admin"); ctx.reconnect(null); ...... // セションをクローズ vctx.close();
1プロセス内で保持できるセション数は最大1024です。1024を超過してセションを生成しようとした場合、SSLExceptionが生成されます。
SSLException エラータイプの値(int):99、SSLエラーコード:200002
アプリケーションで以下の対応をしてください。
利用していないセションをクローズするようにコーディングする。
使用するセションを使いまわすことができる場合は、生成するセション数を減らす。
“複数のセションを必要とする場合”を参照してください。
プロセス数を増やしてセションを振り分けることで、1プロセスあたりのセション数が1024を超過しないようアプリケーション側で対処する。