【问题标题】:How do a LDAP search/authenticate against this LDAP in Java如何在 Java 中针对此 LDAP 进行 LDAP 搜索/身份验证
【发布时间】:2011-01-11 11:37:26
【问题描述】:

我正在使用 LDAP 和 Java 搜索。 这是我的 LDIF 导出的简单组织

version: 1

dn: dc=example,dc=com
objectClass: organization
objectClass: dcObject
objectClass: top
dc: example
o: MyOrganization
description: Test Description

dn: ou=people, dc=example,dc=com
objectClass: organizationalUnit
objectClass: top
ou: people
description: All users in demo company

dn: cn=Johnny Doe,ou=people,dc=example,dc=com
objectClass: organizationalPerson
objectClass: person
objectClass: inetOrgPerson
objectClass: top
cn: Johnny Doe
sn: Johnny
homephone: 123-456-7890
mail: johnny@johnny.com
ou: Development
uid: jjohnny
userpassword:: johnny

dn: cn=Samuel Johnson,ou=people,dc=example,dc=com
objectClass: organizationalPerson
objectClass: person
objectClass: inetOrgPerson
objectClass: top
cn: Samuel Johnson
sn: Samuel
homephone: 123-456-7890
mail: sam@ssam.com
ou: Accounts
uid: ssam
userpassword:: sammy

如何运行 Java sn-p 以从 LDAP 服务器获取所有用户?我的 Apache DS 目录服务器上没有身份验证设置。

Hashtable env = new Hashtable(11);
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:10389/dc=example,dc=com");
env.put(Context.SECURITY_AUTHENTICATION, "none");

try {
    // Create initial context
    DirContext ctx = new InitialDirContext(env);
    Object obj = new Object();
    // want to print all users from the LDAP server
    System.out.println(obj.toString());
    ctx.close();
}

【问题讨论】:

    标签: java ldap jndi


    【解决方案1】:
    try {
        LdapContext ctx = new InitialLdapContext(env, null);
        ctx.setRequestControls(null);
        NamingEnumeration<?> namingEnum = ctx.search("ou=people,dc=example,dc=com", "(objectclass=user)", getSimpleSearchControls());
        while (namingEnum.hasMore ()) {
            SearchResult result = (SearchResult) namingEnum.next ();    
            Attributes attrs = result.getAttributes ();
            System.out.println(attrs.get("cn"));
    
        } 
        namingEnum.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    private SearchControls getSimpleSearchControls() {
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchControls.setTimeLimit(30000);
        //String[] attrIDs = {"objectGUID"};
        //searchControls.setReturningAttributes(attrIDs);
        return searchControls;
    }
    

    【讨论】:

    【解决方案2】:

    另一种方法是使用UnboundID。它的 api 可读性很强,而且更短

    创建 Ldap 连接

    public static LDAPConnection getConnection() throws LDAPException {
        // host, port, username and password
        return new LDAPConnection("com.example.local", 389, "Administrator@com.example.local", "admin");
    }
    

    获取过滤结果

    public static List<SearchResultEntry> getResults(LDAPConnection connection, String baseDN, String filter) throws LDAPSearchException {
        SearchResult searchResult;
    
        if (connection.isConnected()) {
            searchResult = connection.search(baseDN, SearchScope.ONE, filter);
    
            return searchResult.getSearchEntries();
        }
    
        return null;
    }
    

    获取所有组织单元和容器

    String baseDN = "DC=com,DC=example,DC=local";
    String filter = "(&(|(objectClass=organizationalUnit)(objectClass=container)))";
    
    LDAPConnection connection = getConnection();        
    List<SearchResultEntry> results = getResults(connection, baseDN, filter);
    

    获取特定的组织单位

    String baseDN = "DC=com,DC=example,DC=local";
    String dn = "CN=Users,DC=com,DC=example,DC=local";
    
    String filterFormat = "(&(|(objectClass=organizationalUnit)(objectClass=container))(distinguishedName=%s))";
    String filter = String.format(filterFormat, dn);
    
    LDAPConnection connection =  getConnection();
    
    List<SearchResultEntry> results = getResults(connection, baseDN, filter);
    

    获取组织单位下的所有用户

    String baseDN = "CN=Users,DC=com,DC=example,DC=local";
    String filter = "(&(objectClass=user)(!(objectCategory=computer)))";
    
    LDAPConnection connection =  getConnection();       
    List<SearchResultEntry> results = getResults(connection, baseDN, filter);
    

    获取组织单位下的特定用户

    String baseDN = "CN=Users,DC=com,DC=example,DC=local";
    String userDN = "CN=abc,CN=Users,DC=com,DC=example,DC=local";
    
    String filterFormat = "(&(objectClass=user)(distinguishedName=%s))";
    String filter = String.format(filterFormat, userDN);
    
    LDAPConnection connection =  getConnection();
    List<SearchResultEntry> results = getResults(connection, baseDN, filter);
    

    显示结果

    for (SearchResultEntry e : results) {
        System.out.println("name: " + e.getAttributeValue("name"));
    }
    

    【讨论】:

    • 我是否需要为每个请求创建和关闭LDAPConnection
    【解决方案3】:

    你也可以使用下面的代码:

    package com.agileinfotech.bsviewer.ldap;
    
    import java.util.Hashtable;
    import java.util.ResourceBundle;
    
    import javax.naming.Context;
    import javax.naming.NamingException;
    import javax.naming.directory.DirContext;
    import javax.naming.directory.InitialDirContext;
    
    public class LDAPLoginAuthentication {
        public LDAPLoginAuthentication() {
            // TODO Auto-generated constructor
        }
    
        ResourceBundle resBundle = ResourceBundle.getBundle("settings");
    
        @SuppressWarnings("unchecked")
        public String authenticateUser(String username, String password) {
            String strUrl = "success";
            Hashtable env = new Hashtable(11);
            boolean b = false;
            String Securityprinciple = "cn=" + username + "," + resBundle.getString("UserSearch");
            env.put(Context.INITIAL_CONTEXT_FACTORY, resBundle.getString("InitialContextFactory"));
            env.put(Context.PROVIDER_URL, resBundle.getString("Provider_url"));
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, Securityprinciple);
            env.put(Context.SECURITY_CREDENTIALS, password);
    
            try {
                // Create initial context
                DirContext ctx = new InitialDirContext(env);
                // Close the context when we're done
                b = true;
                ctx.close();
    
            } catch (NamingException e) {
                b = false;
            } finally {
                if (b) {
                    strUrl = "success";
                } else {
                    strUrl = "failer";
                }
            }
            return strUrl;
        }
    }
    

    【讨论】:

    • 注意,请注意此实现可能允许用户使用空密码进行身份验证。见stackoverflow.com/questions/12359831/…。根据 LDAP 服务器的实现,您还需要检查密码参数是否为空。
    猜你喜欢
    • 2015-07-28
    • 1970-01-01
    • 2021-09-02
    • 2012-12-30
    • 1970-01-01
    • 2014-03-08
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多