当前位置: 首页 > 知识库问答 >
问题:

LDAP搜索中的NPE

夏兴生
2023-03-14

我安装并配置了OpenLDAP服务器,配置如下:

# Entry 1: dc=unixmen,dc=com
dn: dc=unixmen,dc=com
dc: unixmen
o: unixmen
objectclass: top
objectclass: dcObject
objectclass: organization

# Entry 2: cn=ServerAdmins,dc=unixmen,dc=com
dn: cn=ServerAdmins,dc=unixmen,dc=com
cn: ServerAdmins
gidnumber: 501
objectclass: posixGroup
objectclass: top

# Entry 3: cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com
dn: cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com
cn: rcbandit
gidnumber: 501
givenname: rcbandit
homedirectory: /home/users/rcbandit
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: rcbandit
uid: rcbandit
uidnumber: 1000
userpassword: {MD5}2FeO34RYzgb7xbt2pYxcpA==

我测试了这个简单的Java LDAP客户机,以便通过发送用户名和密码对用户进行身份验证:

public class MainApp
{

    public static String ldapHostUrl = null;
    public static String ldapBindDN = null;
    public static String ldapBindPwd = null;

    public MainApp()
    {

    }

    /**
     * Generic method to obtain a reference to a DirContext
     */
    public DirContext getDirContext() throws Exception
    {
        Hashtable<String, String> env = new Hashtable<String, String>(11);
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, getLdapHostUrl());
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, ldapBindDN);
        env.put(Context.SECURITY_CREDENTIALS, ldapBindPwd);
        DirContext ctx = new InitialDirContext(env);
        return ctx;
    }

    /**
     * Generic method to obtain a reference to the user ENV
     */
    public static Hashtable<String, String> getUserEnv()
    {
        Hashtable<String, String> env = new Hashtable<String, String>(11);
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, getLdapHostUrl());
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        return env;
    }

    /**
     *
     * @param attributeName String - Standard ID (userID)
     * @throws Exception -
     */
    public void doFindEntries(String attributeValue, String attributeName, String searchBase) throws Exception
    {
        DirContext xctx = getDirContext();
        SearchControls searchCons = getSimpleSearchControls();
        String searchFilter = "(" + attributeName + "=" + attributeValue + ")";
        // Search for objects with those matching attributes
        NamingEnumeration<?> answer = xctx.search(searchBase, searchFilter, searchCons);
        //formatResults(answer);
        xctx.close();
    }

    public String getDN(String name, String ldapUserIDAttribute, String ldapBaseForusers) throws NamingException, Exception
    {
        String dn = null;
        String searchFilter = "(" + ldapUserIDAttribute + "=" + name + ")";
        SearchControls searchCons = getSimpleSearchControls();
        searchCons.setReturningAttributes(new String[0]);
        NamingEnumeration<?> results = getDirContext().search(ldapBaseForusers, searchFilter, searchCons);
        int thisCount = 0;
        if (results != null && results.hasMore())
        {
            if (thisCount > 0)
            {
                throw new NamingException("More than one Result was found!");
            }
            SearchResult si = (SearchResult) results.next();
            dn = si.getNameInNamespace();
            thisCount++;
        }
        return dn;
    }

    /**
     * I am just lazy and hate to type.
     *
     * @return
     */
    public static SearchControls getSimpleSearchControls()
    {
        SearchControls searchControls = new SearchControls();
        searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchControls.setTimeLimit(30000);
        return searchControls;
    }

    public static void testUserCredentials(String userFdn, String userPassword) throws NamingException
    {
        Hashtable<String, String> userEnv = getUserEnv();
        userEnv.put(Context.SECURITY_PRINCIPAL, userFdn);
        userEnv.put(Context.SECURITY_CREDENTIALS, userPassword);
        DirContext userCtx = new InitialDirContext(userEnv);
    }

    /**
     * Reads from console and works in Eclipse
     *
     * @param prompt
     * @return
     */
    private static String readLine(String prompt)
    {
        String line = null;
        Console c = System.console();
        if (c != null)
        {
            line = c.readLine(prompt);
        }
        else
        {
            System.out.print(prompt);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
            try
            {
                line = bufferedReader.readLine();
            }
            catch (IOException e)
            {
                // Ignore
            }
        }
        return line;
    }

    static String getLdapHostUrl()
    {
        return ldapHostUrl;
    }

    static void setLdapHostUrl(String ldapHostUrl)
    {
        ldapHostUrl = ldapHostUrl;
    }

    static String getLdapBindDN()
    {
        return ldapBindDN;
    }

    static void setLdapBindDN(String ldapBindDN)
    {
        ldapBindDN = ldapBindDN;
    }

    static String getLdapBindPwd()
    {
        return ldapBindPwd;
    }

    static void setLdapBindPwd(String ldapBindPwd)
    {
        ldapBindPwd = ldapBindPwd;
    }

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        System.out.println("Performing LDAP Operations with the Following:");

        MainApp ss = new MainApp();
        MainApp.setLdapHostUrl("ldap://192.168.1.177:389");
        MainApp.setLdapBindDN("cn=rcbandit,cn=ServerAdmins,dc=unixmen,dc=com");
        MainApp.setLdapBindPwd("qwerty");
        String ldapBaseForusers = "cn";
        String ldapUserIDAttribute = "simple";

        while (true)
        {
            String userFindValue = null;
            String userFdn = null;
            String userPassword = null;
            // /Find a user
            userFindValue = "rcbandit";
            userPassword = "qwerty";
            System.out.println("Return All Attributes for ALL users by: " + ldapUserIDAttribute + " = " + userFindValue);

            try
            {
                ss.doFindEntries(userFindValue, ldapUserIDAttribute, ldapBaseForusers);
            }
            catch (javax.naming.PartialResultException e)
            {
                System.out.println("Find user DN by Name: Returned a PartialResultException\n" + e.getMessage());
            }
            catch (Exception e)
            {
                System.out.println("Find user DN by Name: FAILED\n" + e.getMessage());
            }

            System.out.println();
            System.out.println("Find user DN by: " + ldapUserIDAttribute + " = " + userFindValue);
            System.out.println("====================================================");
            try
            {
                userFdn = ss.getDN(userFindValue, ldapUserIDAttribute, ldapBaseForusers);
                System.out.println("DN: " + userFdn);
            }
            catch (NamingException e)
            {
                if (e instanceof javax.naming.PartialResultException)
                {
                    // ignore
                }
                else
                {
                    System.out.println("Find user DN by Name: Returned a PartialResultException\n" + e.getMessage());
                }
            }
            catch (Exception e)
            {
                System.out.println("Find user DN by Name: FAILED\n" + e.getMessage());
            }
            System.out.println();
            System.out.println("Test User's Credentials: ");
            System.out.println("====================================================");
            try
            {
                testUserCredentials(userFdn, userPassword);
                System.out.println("Test User's Credentials: SUCCESS!");
            }
            catch (NamingException e)
            {
                System.err.println("Test User's Credentials: FAILED\n" + e.getMessage());
            }
        }// end while
    }
}
Find user DN by: simple = rcbandit
====================================================
Find user DN by Name: FAILED
null

Test User's Credentials: 
====================================================
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.javafx.main.Main.launchApp(Main.java:714)
    at com.javafx.main.Main.main(Main.java:871)
Caused by: java.lang.NullPointerException
    at java.util.Hashtable.put(Hashtable.java:514)
    at dx57.ldapclient.MainApp.getUserEnv(MainApp.java:52)
    at dx57.ldapclient.MainApp.testUserCredentials(MainApp.java:109)
    at dx57.ldapclient.MainApp.main(MainApp.java:240)
    ... 6 more

共有1个答案

南宫天逸
2023-03-14

我会说'get ldaphosturl()'返回null,但我也会说,您真的很想调试自己的NPE,尤其是像这样一个微不足道的NPEs。至少我预料到了。

 类似资料:
  • 问题内容: 我正在使用JNDI连接到LDAP活动目录,并且我想搜索名称包含搜索字符串的用户,因此我的搜索方法如下: 这是我与LDAP建立连接的方式: LDAP凭证如下: 为什么搜索需要那么多时间来检索数据?由于广告中只有285个联系人,我可以做些什么来加快搜索速度吗? 问题答案: 解决方案是更改为

  • LDAP新手。我们LDAP的排列方式是人和组。这些人拥有用户信息,如姓名、uid和邮件。组有组名和multiple member字段,该字段的值为cn=first Last,cn=People,dc=comic,dc=com,列出了属于组的成员。 目前从userid和password开始,执行两个搜索:1)通过在People base domain上搜索uid=value来获取用户,然后从用户获得

  • 问题内容: 我正在玩LDAP和Java搜索。这是我的一个简单组织的LDIF导出 如何运行Java代码段以从LDAP服务器获取所有用户?我的Apache DS目录服务器上没有身份验证设置。 问题答案:

  • 我正在使用LDAP从我的应用程序连接到AD服务器。我成功地通过了身份验证,但是当我搜索一个用户时,它会抛出一个异常,在acl_read:instanceType中的LDAP错误代码为32。 谢谢