LDAP再認証


概要 ：　SOS用ユーザのLDAP認証が失敗した際に認証を救済する。

処理概要： １. LDAP検索用ユーザが認証したユーザの組織情報の検索を行う。
　　　　　 ２. 検索結果により、正しい組織情報を用いて再度認証を行う。

前提条件： LDAP検索用ユーザがLDAPサーバ側に用意されている事。

※ 戻り値によりエラー内容を識別しているため、当処理は必ず例外処理内に記述してください。

※ LDAPサーバのURI,ポート,ドメイン,組織情報等については各自設定をお願いいたします。

※ FRONT_SGはxmlファイルです。
　 xmlファイルのタグ参照は必須ではないため、
　 各プロパティに直接値を設定してください。

・ LDAP認証プロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339882/67759b5d-713b-4f71-10eb-e9501fca71f4.png)

・ソース

```java
    public static int authenticationLDAP_try(String strUserID, String strUserPass) {
        
		Hashtable env = new Hashtable();
    	String strErrMsg = "";

		//LDAP組織情報の取得
    	String userOU = null;
    	String userID = strUserID;
    	String userPW = strUserPass;
		
		env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, LdapUri + ":" + LdapPortNo + "/");
		env.put(Context.SECURITY_AUTHENTICATION, "simple");


        	// LDAP検索
        	// 最初の","を除く
        	String BaseDN = StringUtils.substring(LdapOU, 1);
        	
        	// LDAP検索用cnで接続する
            env.put(Context.SECURITY_PRINCIPAL, LdapUser + "," + BaseDN);
    		env.put(Context.SECURITY_CREDENTIALS, LdapUserPw);
    		
            // 検索するための設定を取得します。
    	    DirContext dirContext = null;
    	    String LDAP_con_step = "1";		// LDAP検索用ユーザで接続
    	    try {
                // LDAP検索用ユーザで接続
    	    	dirContext = new InitialDirContext(env);
           	    
    	    	LDAP_con_step = "2";		// LDAP認証
    	    	
                SearchControls searchControls = new SearchControls();
                searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
                
                // 検索フィルタにユーザIDを設定します。
                String filter = "uid=" + userID;
                // LDAP でユーザの検索を実行します。
                NamingEnumeration<SearchResult> searchResult = dirContext.search(BaseDN, filter , searchControls);
                
                //検索が終了したのでログアウトします。
                
                // 検索結果が存在するかを判定します。
                if (searchResult.hasMoreElements()) {
                    SearchResult sr = (SearchResult) searchResult.nextElement();
                    // ユーザの検索結果を基にパスワードの検証を行う
                    // パスワードを認証情報として LDAP サーバに認証を依頼します。

                    // LDAPの組織情報（uidとou）を取得する。
                    
                    //エントリーを取得
                    String strLDAPDir = sr.getName();
                    
            		//エントリーのou情報を取得する
                    userOU = "," + StringUtils.substring(strLDAPDir, strLDAPDir.indexOf("ou="));
                    
            		//検索コネクションが蓄積するため解放
            		searchResult.close();
                    
                    env.put(Context.SECURITY_PRINCIPAL, "uid=" + userID + userOU + LdapOU);
                    
                    env.put(Context.SECURITY_CREDENTIALS, userPW);
                    //
                    
                    dirContext = new InitialDirContext(env);
                    dirContext.close();
                    // ここまで来たら LDAP 認証成功したこととします。
                    
                } else {
                	dirContext.close();
    	    		strErrMsg = "ユーザが存在しません。 ユーザ名:" + strUserID;
            		LogUtil.getTraceLogger().abnormalLog(strErrMsg);
        	        return -2;
                }
    	    } catch (NamingException e) {
    	        // ユーザ検索、パスワードの検証に失敗した場合
    	    	if ("1".equals(LDAP_con_step)) {
    	    		strErrMsg = "LDAP検索用ユーザで接続に失敗しました。";
    	    		LogUtil.getTraceLogger().abnormalLog(strErrMsg + LogUtil.makeTraceString(e));
    	    		return -1;
    	    	} else if("2".equals(LDAP_con_step)){
    	    		strErrMsg = "ユーザ・パスワードの認証に失敗しました。";
    	    		LogUtil.getTraceLogger().abnormalLog(strErrMsg + LogUtil.makeTraceString(e));
    	    		return -3;
    	    	}
    	    	strErrMsg = "LDAPサーバへの接続エラーを検知しました。:" + strUserID;
        		LogUtil.getTraceLogger().abnormalLog(strErrMsg + LogUtil.makeTraceString(e));
    	        return -9;
    	    } catch (Exception e) {
    	        // その他例外が発生した場合
        		//　エラー トーレスログ出力
        		LogUtil.getTraceLogger().abnormalLog("LDAPサーバへの接続エラーを検知しました。："
        				+ LogUtil.makeTraceString(e));
    	        return -9;
    	    }
	        return 0;
    }
```