JavaでLDAP認証する方法
JavaでLDAP認証する方法です。
企業の社内システムでは、LDAPを使って認証をおこなっているケースがあります。今回、初めてLDAP認証システムへ関わる機会があったのでテストソースを残しておきます。
javax.namingパッケージを使えば割と簡単にLDAP認証ができますよ。
ここでは JavaでLDAP認証する方法 を紹介します。
LDAPの属性値を理解する
LDAPの属性値は企業によって設定が様々です。当然ですが、ディレクトリサービスにどのような定義がされているかは事前に確認が必要です。
LDAPの 属性値 | 属性表示名 | オブジェクトタイプ |
---|---|---|
cn | Common-Name | ユーザー名、グループ名、コンピュータ名、コンテナ名 |
ou | Organizational-Unit-Name | 組織単位 |
dc | Domain-Component | ドメイン |
例えば、ドメイン「saka-en.com」の組織「developers」に配置したユーザー「Ken」は以下のように示されます。
cn=Ken, ou=developers, dc=saka-en, dc=com
この辺りは、検索すれば詳しく説明してくれているサイトがたくさんあるので、事前に調査しておきましょう。
JavaでLDAP認証する
JavaでLDAP認証するポイントは2つです。
- LDAPサーバーへ接続する。
- ID/パスワード使用してユーザー認証する。
認証OKなら取得できた情報をコンソールへ出力し、認証NGならエラーメッセージをコンソールへ表示してみましょう。
テストコードはこうなります。
package ldaptest;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public class LdapTest {
/**
* LDAP 認証テスト
*/
public static void main(String[] args) throws NamingException {
// LDAP接続情報
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389"); // LDAPサーバー
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=systems,o=group"); // ID, 組織
env.put(Context.SECURITY_CREDENTIALS, "secret"); // パスワード
// 認証したいID・パスワード
String userId = "user001";
String password = "p@ss001";
DirContext ctx = new InitialDirContext(env);
try {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> searchResult = ctx.search("", "uid=" + userId, searchControls);
Attributes attrs = (Attributes)searchResult.nextElement().getAttributes();
System.out.println(attrs.toString());
Hashtable<String, String> uenv = new Hashtable<>(env);
uenv.put(Context.SECURITY_PRINCIPAL, "cn=" + cn + ", ou=staff, o=company, o=group");
uenv.put(Context.SECURITY_CREDENTIALS, password);
DirContext uctx = new InitialDirContext(uenv);
uctx.close();
System.out.println("認証OK");
} catch (AuthenticationException e) {
System.out.println("ユーザーID、パスワードが違います。");
} catch (Exception e) {
System.out.println("ユーザーID、パスワードが違います。");
} finally {
ctx.close();
}
}
}
認証が失敗すると AuthenticationException が発生します。例外が発生しなければ認証OKとなります。
認証が失敗する場合の対処方法
LDAPサーバーへは接続できている、ユーザーIDもパスワードも一致しているのに認証が失敗する場合には、下記のコードを実行してみてください。
while (searchResult != null && searchResult.hasMore()) {
SearchResult si = (SearchResult)searchResult.next();
// エントリ名の出力
System.out.println("name: " + si.getName());
Attributes attrs = si.getAttributes();
if (attrs == null)
System.out.println("No attributes");
else {
// 属性の出力
for (NamingEnumeration<?> ae = attrs.getAll();
ae.hasMoreElements(); ) {
Attribute attr = (Attribute)ae.next();
String attrId = attr.getID();
// 属性値の出力
for (Enumeration<?> vals = attr.getAll();
vals.hasMoreElements();
System.out.println(attrId + ": " + vals.nextElement()));
}
}
System.out.println();
}
多くの場合、属性の設定ミスや属性値の違いなどによるものだと思うので、出力結果をよく見て調整してみてください。
まとめ
JavaでLDAP認証する方法を紹介しました。
思ったより簡単にLDAP認証ができてよかったです。ハマる要素があるとすればLDAPの属性値の組み立てでしょうかね。
皆さんも試してみてください。
おつかれさまでした。