java - 使用 Tomcat 的 Active Directory LDAP 身份验证

标签 java tomcat ldap

自从我开始在 Tomcat 服务器上使用 Active Directory LDAP 已经过去一天了。

我还没有看到将 Active Directory LDAP 与 Tomcat 结合使用的清晰简单示例(如登录模块),而且我刚刚从我访问的 LDAP 服务器的管理员那里获得了以下详细信息。

下面的代码看起来很简单,但我遇到了下面的异常。

  1. 字符串服务器 = "192.168.71.116";//服务器主机名
  2. int 端口 = 50001;
  3. String basedn = "DC=cblan-test,DC=mblox,DC=com";

我传入从请求对象中选取的用户名和密码。

这是我使用的主要代码,我从 here 得到这个例子

<%
    String user = request.getParameter("user");
    String password = request.getParameter("password");

    String filter = "(|(uid=" + user + ")" + "(mail=" + user + "@*))";
    String cliEquiv = "<tt>ldapsearch -h " + server + " -p " +
            port + " -b " + basedn + " \"" + filter + "\"</tt></p>";
    %>
    <p>Equivalent command line:<br /><%= cliEquiv%><hr />
    <%
    // Connect to the LDAP server.
    Hashtable env = new Hashtable(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY,
            "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://" + server + ":" + port + "/");

    // Search and retrieve DN.
    try {
        LdapContext ldap = new InitialLdapContext(env, null);
        NamingEnumeration results = ldap.search(basedn, filter, null);
        String binddn = "None";
        while (results.hasMore()) {
            SearchResult sr = (SearchResult) results.next();
            binddn = sr.getName() + "," + basedn;
        }
    %>
    <p>Bind DN found: <%= binddn%><hr /></p>
    <%
        ldap.close();

        // Authenticate
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, binddn);
        env.put(Context.SECURITY_CREDENTIALS, password);

        ldap = new InitialLdapContext(env, null);
    %>
    <p>Successful authentication for <%= user%>.</p>

这是我的 LDAP 服务器详细信息

我得到了以下我不太理解的异常,我尝试了很多建议但没有结果。谁能帮我解决这个问题,这将帮助我继续基于此构建我的应用程序。还请提供有关在 Tomcat 中使用 Active Directory LDAP 进行身份验证的建议。

2013 年 9 月 17 日下午 1:40:32 org.apache.catalina.realm.JNDIRealm 验证 严重:执行身份验证异常 javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C09062B, comment: 为了执行此操作,必须在连接上完成成功的绑定(bind)。 , 数据 0,va28

最佳答案

注意:您使用 UID 的过滤器,而 AD 本身不支持此属性

第二次检查下面的代码,以便能够以正确的方式连接

package lib;


/**
 * @author sghaida
 *
 */


import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.security.cert.CertificateException;

import ccc.gr.moa.server.FTPMIServiceImpl;

import com.extjs.gxt.ui.client.data.BaseModel;

public class ADConnector {

    /**
     * @param args
     */

    @SuppressWarnings("unchecked")
    static  Hashtable<String, String> envGC = new Hashtable();

    static String adminName;
    static String adminPassword;
    static String urlGC;
    static String searchBase;

    static LdapContext ctxGC;


    public ADConnector() throws NamingException
    {

        //get AD properties
        urlGC = "ldap://" + FTPMIServiceImpl.ADProperties.get("ADHostname")+ ":3268";
        adminName = FTPMIServiceImpl.ADProperties.get("bindDN");
        adminPassword = FTPMIServiceImpl.ADProperties.get("bindPassword");
        searchBase = FTPMIServiceImpl.ADProperties.get("searchBase");


        envGC.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        //envDC.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");

        //set security credentials, note using simple cleartext authentication
        envGC.put(Context.SECURITY_AUTHENTICATION,"simple");
        envGC.put("java.naming.ldap.attributes.binary","userCertificate");
        envGC.put(Context.SECURITY_PRINCIPAL,adminName);
        envGC.put(Context.SECURITY_CREDENTIALS,adminPassword);

        //envDC.put(Context.SECURITY_AUTHENTICATION,"simple");
        //envDC.put(Context.SECURITY_PRINCIPAL,adminName);
        //envDC.put(Context.SECURITY_CREDENTIALS,adminPassword);

        //connect to both a GC and  DC
        envGC.put(Context.PROVIDER_URL,urlGC);
        //envDC.put(Context.PROVIDER_URL,urlDC);
        //Create the initial directory context for both DC and GC
        ctxGC = new InitialLdapContext(envGC,null);
        //ctxDC = new InitialLdapContext(envDC,null);
    }

    /**
     * @param name
     * @return
     * @throws NamingException
     */
    /**
     * @param name
     * @return
     * @throws NamingException
     */
    public List<BaseModel> searchResults(String searchFilter ) throws NamingException
    {
        //Create the search controls        
        SearchControls searchCtls = new SearchControls();

        //Specify the attributes to return
        //String returnedAtts[]={"sn","givenName","mail","userCertificate"};
        String returnedAtts[]={"cn","sn","givenName","sAMAccountName","mail","distinguishedName"};
        searchCtls.setReturningAttributes(returnedAtts);


        //Specify the search scope
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        //Specify the Base for the search
        //String searchBase = "dc=ccg,dc=local";

        //initialize counter to total the results
        int totalResults = 0;

        //Search for objects in the GC using the filter
        NamingEnumeration answer = ctxGC.search(searchBase, searchFilter, searchCtls);

        List<BaseModel> results = new ArrayList<BaseModel>();

        while (answer.hasMoreElements()) {

            SearchResult sr = (SearchResult)answer.next(); 
            totalResults++;

            // Print out some of the attributes, catch the exception if the attributes have no values

            Attributes attrs = sr.getAttributes();
            if (attrs != null) {
                try {

                    System.out.println("   cn(GC): " + attrs.get("cn").get());
                    System.out.println("   sn(GC): " + attrs.get("sn").get());
                    System.out.println("   givenName(GC): " + attrs.get("givenName").get());
                    System.out.println("   mail(GC): " + attrs.get("mail").get());
                    System.out.println("   sAMAccountName(GC): " + attrs.get("sAMAccountName").get());
                    System.out.println("   distinguishedName(GC): " + attrs.get("distinguishedName").get());

                    BaseModel bm = new BaseModel();

                    bm.set("full_name", attrs.get("cn").get());
                    bm.set("last_name", attrs.get("sn").get());
                    bm.set("first_name", attrs.get("givenName").get());

                    bm.set("email",attrs.get("mail").get());
                    bm.set("account_name", attrs.get("sAMAccountName").get());

                    results.add(bm);

                }
                catch (NullPointerException e)  {
                    System.err.println("Problem listing attributes from Global Catalog: " + e);
                    e.printStackTrace();
                }

            }

        }
        ctxGC.close();
        return results;

    }


    public static void main(String[] args) throws CertificateException, NamingException {

        ADConnector connector = new ADConnector();
        //specify the LDAP search filter
        String searchFilter = "(sAMAccountName=sghaida)";
        List<BaseModel> results = connector.searchResults(searchFilter);


    }

}

关于java - 使用 Tomcat 的 Active Directory LDAP 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18850466/

相关文章:

apache - 在 Apache Tomcat 5.5 上播放 FLV 时出现问题

tomcat - 从数据库打开 Xlsx

java - 子错误代码 568 对于 Active Directory 的 Ldap 错误 49 意味着什么

bash - 如何阻止 ldapsearch(1) 对 userPassword 和其他属性进行 base64 编码?

java - 如何使用 LDAP Java API 创建 SharePoint 2013 用户组

java - 如何比较数组元素并将相应元素添加到第三个数组?

java - 胖 JAR 的 gradle 替代品是什么?

java - Java 中的内联是什么? final 关键字和内联之间有什么关系吗?

java - 获取 Swing GridLayout 中特定行和列的小部件

java - 在两个 Web 应用程序之间共享请求对象