如何使用Apache Directory Server和Client Java API实现身份验证

时间:2017-01-18 18:05:05

标签: java ldap apache-directory

我正在尝试构建一个应用程序,其中将在Apache Directory Server及其客户端API中管理用户和组。

这是应用程序启动时针对服务器执行的ldif文件的示例:

dn: o=koosserydesk objectclass: extensibleObject objectclass: top objectclass: domain dc: koosserydesk o: koosserydesk
dn: ou=desks,o=koosserydesk objectClass: organizationalUnit objectClass: top ou: desks
dn: ou=users,o=koosserydesk objectClass: organizationalUnit objectClass: top ou: users
dn: cn=John Milton,ou=users,o=koosserydesk objectClass: organizationalPerson objectClass: person objectClass: inetOrgPerson objectClass: top cn: John Milton sn: jmilton uid: jmilton userPassword:: e1NIQTUxMn1lQThmcUQzOVgva2xxSm1jOGlZK2JoWitUVFhzWElFRmZHeWJ1b

我想让John Milton在输入相应的uid / userPassword时被识别为我的应用的经过身份验证的用户。类似的东西:

Boolean authenticate(String uid){
//should i use connection.bind("uid="+uid, userPassword);??
return something; }

请注意,John Milton针对ApacheDS进行身份验证(对条目采取行动)对我来说并不是最重要的。我只是希望ApacheDs为我的用户充当数据库,即取用我的用户的uid,检查密码,如果匹配返回true,则返回false
可能这不是我应该尝试处理的方式,但我对Ldap协议和其他东西都是新手,所以不要怀疑我的问题是否有点奇怪!
等待命题!

1 个答案:

答案 0 :(得分:0)

这可能不是重复,但第二个答案(尼古拉安提波夫)对以下问题可能会回答你的问题: How to check user password in ldap whith java with given LdapContext?

这是一种解决方案,可用于使用除DN之外的其他内容对用户进行身份验证,例如使用uidsAMAccountName

要做的步骤是:

  1. 连接到LDAP服务器
  2. 与我们了解DN和凭据的服务用户进行身份验证
  3. 搜索要进行身份验证的用户,使用某个属性搜索他(例如sAMAccountName
  4. 获取我们找到的用户的DN
  5. 使用找到的DN和密码
  6. 打开与LDAP服务器的另一个连接
  7. 如果找到用户并且身份验证有效,那么
  8. 代码示例:

    public static boolean performAuthentication() {
    
        // service user
        String serviceUserDN = "cn=Mister Service,ou=Users,dc=example,dc=com";
        String serviceUserPassword = "abc123#!$";
    
        // user to authenticate
        String identifyingAttribute = "uid";
        String identifier = "maxdev";
        String password = "jkl987.,-";
        String base = "ou=Users,dc=example,dc=com";
    
        // LDAP connection info
        String ldap = "localhost";
        int port = 10389;
        String ldapUrl = "ldap://" + ldap + ":" + port;
    
        // first create the service context
        DirContext serviceCtx = null;
        try {
            // use the service user to authenticate
            Properties serviceEnv = new Properties();
            serviceEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            serviceEnv.put(Context.PROVIDER_URL, ldapUrl);
            serviceEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
            serviceEnv.put(Context.SECURITY_PRINCIPAL, serviceUserDN);
            serviceEnv.put(Context.SECURITY_CREDENTIALS, serviceUserPassword);
            serviceCtx = new InitialDirContext(serviceEnv);
    
            // we don't need all attributes, just let it get the identifying one
            String[] attributeFilter = { identifyingAttribute };
            SearchControls sc = new SearchControls();
            sc.setReturningAttributes(attributeFilter);
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
    
            // use a search filter to find only the user we want to authenticate
            String searchFilter = "(" + identifyingAttribute + "=" + identifier + ")";
            NamingEnumeration<SearchResult> results = serviceCtx.search(base, searchFilter, sc);
    
            if (results.hasMore()) {
                // get the users DN (distinguishedName) from the result
                SearchResult result = results.next();
                String distinguishedName = result.getNameInNamespace();
    
                // attempt another authentication, now with the user
                Properties authEnv = new Properties();
                authEnv.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                authEnv.put(Context.PROVIDER_URL, ldapUrl);
                authEnv.put(Context.SECURITY_PRINCIPAL, distinguishedName);
                authEnv.put(Context.SECURITY_CREDENTIALS, password);
                new InitialDirContext(authEnv);
    
                System.out.println("Authentication successful");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (serviceCtx != null) {
                try {
                    serviceCtx.close();
                } catch (NamingException e) {
                    e.printStackTrace();
                }
            }
        }
        System.err.println("Authentication failed");
        return false;
    }