39

アプリケーションの LDAP 認証を行う必要があります。

次のプログラムを試しました。

import java.util.Hashtable;  

import javax.naming.Context;  
import javax.naming.NamingException;  
import javax.naming.ldap.InitialLdapContext;  
import javax.naming.ldap.LdapContext;  


public class LdapContextCreation {  
    public static void main(String[] args) {  
        LdapContextCreation ldapContxCrtn = new LdapContextCreation();  
        LdapContext ctx = ldapContxCrtn.getLdapContext();  
    }  
    public LdapContext getLdapContext(){  
        LdapContext ctx = null;  
        try{  
            Hashtable env = new Hashtable();  
            env.put(Context.INITIAL_CONTEXT_FACTORY,  "com.sun.jndi.ldap.LdapCtxFactory");  
            env.put(Context.SECURITY_AUTHENTICATION, "Simple");  
            //it can be <domain\\userid> something that you use for windows login  
            //it can also be  
            env.put(Context.SECURITY_PRINCIPAL, "username@domain.com");  
            env.put(Context.SECURITY_CREDENTIALS, "password");  
            //in following property we specify ldap protocol and connection url.  
            //generally the port is 389  
            env.put(Context.PROVIDER_URL, "ldap://server.domain.com");  
            ctx = new InitialLdapContext(env, null);  
            System.out.println("Connection Successful.");  
        }catch(NamingException nex){  
            System.out.println("LDAP Connection: FAILED");  
            nex.printStackTrace();  
        }  
        return ctx;  
    }  

}

次の例外を取得:

LDAP 接続: 失敗しました
javax.naming.AuthenticationException: [LDAP: エラーコード 49 - 無効な資格情報]
    com.sun.jndi.ldap.LdapCtx.mapErrorCode (LdapCtx.java:3053) で
    com.sun.jndi.ldap.LdapCtx.processReturnCode (LdapCtx.java:2999) で
    com.sun.jndi.ldap.LdapCtx.processReturnCode (LdapCtx.java:2801) で
    com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2715) で
    com.sun.jndi.ldap.LdapCtx.(LdapCtx.java:305) で
    com.sun.jndi.ldap.LdapCtxFactory.getUsingURL (LdapCtxFactory.java:187) で
    com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:205) で
    com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance (LdapCtxFactory.java:148) で
    com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:78) で
    javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:235)で
    javax.naming.InitialContext.initializeDefaultInitCtx(InitialContext.java:318)で
    javax.naming.InitialContext.getDefaultInitCtx (InitialContext.java:348) で
    javax.naming.InitialContext.internalInit(InitialContext.java:286) で
    javax.naming.InitialContext.init(InitialContext.java:308) で
    javax.naming.ldap.InitialLdapContext.(InitialLdapContext.java:99) で
    LdapContextCreation.getLdapContext(LdapContextCreation.java:27) で
    LdapContextCreation.main (LdapContextCreation.java:12) で

考慮すべき点がいくつかあります。

  1. 以前は使用してtomcat 5.3.5いましたが、Tomcat 6 のみがサポートしていると誰かに言われたので、ダウンロードtomcat 6.0.35して現在このバージョンのみを使用しています。

  2. server.xml次のコードを構成して追加しました-

    <Realm className="org.apache.catalina.realm.JNDIRealm" 
                       debug="99" 
                       connectionURL="ldap://server.domain.com:389/"  
                       userPattern="{0}" />
    
  3. から次のコードにコメントしましたserver.xml-

    <!-- Commenting for LDAP
      <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
         resourceName="UserDatabase"/> -->
    
  4. 記事のステップ 2 と 3

  5. 認証を実行するために tomcat にコピーする必要がある jar ファイルがいくつかあると誰かが提案しましたが、ldapそれは私がする必要がありますか? そして、どのjarファイルですか?

  6. また、確かに正しい資格情報を使用していますが、この問題の原因は何ですか?

  7. 間違った属性を使用している場合に、LDAP の正しい属性を特定する方法はありますか?

4

4 に答える 4

35

次のコードは、純粋な Java JNDI を使用して LDAP から認証します。原則は次のとおりです。

  1. まず、管理者または DN ユーザーを使用してユーザーを検索します。
  2. ユーザー資格情報を使用して、ユーザー オブジェクトを LDAP に再度渡す必要があります。
  3. 例外なしとは、認証に成功したことを意味します。そうでなければ認証に失敗しました。

コードスニペット

public static boolean authenticateJndi(String username, String password) throws Exception{
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    props.put(Context.PROVIDER_URL, "ldap://LDAPSERVER:PORT");
    props.put(Context.SECURITY_PRINCIPAL, "uid=adminuser,ou=special users,o=xx.com");//adminuser - User with special priviledge, dn user
    props.put(Context.SECURITY_CREDENTIALS, "adminpassword");//dn user password


    InitialDirContext context = new InitialDirContext(props);

    SearchControls ctrls = new SearchControls();
    ctrls.setReturningAttributes(new String[] { "givenName", "sn","memberOf" });
    ctrls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    NamingEnumeration<javax.naming.directory.SearchResult> answers = context.search("o=xx.com", "(uid=" + username + ")", ctrls);
    javax.naming.directory.SearchResult result = answers.nextElement();

    String user = result.getNameInNamespace();

    try {
        props = new Properties();
        props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        props.put(Context.PROVIDER_URL, "ldap://LDAPSERVER:PORT");
        props.put(Context.SECURITY_PRINCIPAL, user);
        props.put(Context.SECURITY_CREDENTIALS, password);

   context = new InitialDirContext(props);
    } catch (Exception e) {
        return false;
    }
    return true;
}
于 2014-07-15T07:19:17.113 に答える
7

ユーザー全体を提供する必要がありdnますSECURITY_PRINCIPAL

このような

env.put(Context.SECURITY_PRINCIPAL, "cn=username,ou=testOu,o=test"); 
于 2012-09-07T11:41:31.750 に答える