2017年11月2日
JavaでActiveDirectory検索を行う(AD認証)
JavaでActiveDirectory検索を行う(AD認証)
JNDIを利用し、ActiveDirectoryへアクセスする。
JNDIを利用し、ActiveDirectoryへアクセスしユーザ認証を行う方法を紹介します。
※参考資料
https://www.intra-mart.jp/document/library/iap/public/im_certification/im_certification_programming_guide/texts/example/index.html
上記のサンプルをより汎用的に改良しました。
■JNDIとは
Java Naming and Directory Interfaceの略で、ネームサービスやディレクトリーサービスにアクセスする方法
ActiveDirectoryも「ディレクトリサービス」となります。
ActiveDirectoryとは、ユーザー、組織やグループ、コンピューター、プリンタ、共有フォルダなどの情報を管理します。
今回はユーザをJavaを用いて検索する方法についてご紹介します。
■Javaでの実現方法
Javaでディレクトリサービスを操作する場合は、以下を利用します。
Javaでディレクトリ操作を実行するためのAPIとなります。
本コンテキストに接続情報、ユーザ情報などを設定するだけで簡単にアクセスが可能となります。
■サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /** * LDAP 認証サーバに認証を依頼します。 */ public static void main(String args[]) { String userId = "test_user" ; final String baseDn = "CN=Users,DC=test,DC=local" ; Hashtable<String, String> env = new Hashtable<String, String>(); // Contextファクトリ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" ); // AD接続先URL env.put(Context.PROVIDER_URL, providerUrl); // セキュリティレベル env.put(Context.SECURITY_AUTHENTICATION, "simple" ); // ユーザID+ドメイン env.put(Context.SECURITY_PRINCIPAL, "admin" + "@" + "test.local" ); // パスワード env.put(Context.SECURITY_CREDENTIALS, "adminp@ss" ); DirContext dirContext = null ; try { // 検索するための設定を取得します。 dirContext = new InitialDirContext(env); // 検索範囲の指定 SearchControls searchControls = new SearchControls(); searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); // 検索フィルタにユーザコードを設定します。 String filter = "cn=" ; // LDAP でユーザの検索を実行します。 NamingEnumeration<SearchResult> searchResult = dirContext.search(baseDn, filter + userId, searchControls); // 検索結果が存在するかを判定します。 if (searchResult.hasMoreElements()) { SearchResult sr = (SearchResult) searchResult.nextElement(); // ユーザの検索結果を基にパスワードの検証を行う // パスワードを認証情報として LDAP サーバに認証を依頼します。 String userName = sr.getName(); String password = "user_p@ss" ; env.put(Context.SECURITY_PRINCIPAL, userName + "," + baseDn); env.put(Context.SECURITY_CREDENTIALS, password); dirContext = new InitialDirContext(env); // ここまで来たら LDAP 認証成功したこととします。 System.out.println( "CertificationStatus.CR_OK" ); return ; } else { System.out.println( "ユーザが存在しません. ユーザ名:" + userId); return ; } } catch (NamingException e) { // ユーザ検索、パスワードの検証に失敗した場合 System.out.println( "ユーザ検索、パスワードの検証に失敗" ); e.printStackTrace(); } catch (Exception e) { // その他例外が発生した場合 e.printStackTrace(); } finally { try { dirContext.close(); } catch (NamingException e) { e.printStackTrace(); } } } |
■注意点
上記サンプルでは、「ldap://XXXXX.test.local」のようにSSL通信ではない形式で指定しています。
セキュリティの観点から、必ず「ldaps」を利用する事をおすすめします。
又、47行目のパスワードに空を指定した場合、匿名として認証が成功してしまう為、上記サンプルでは行っていませんが、事前に空チェックを行う必要がございます。