简体   繁体   English

验证用户名密码Java ldap jndi

[英]Validate username password java ldap jndi

I'm trying to figure out a simple way to validate a username and password using Java (JNDI) , after I've already connected to the LDAP using a bind (bind DN and password). 在使用绑定(绑定DN和密码)连接到LDAP之后,我试图找出一种使用Java (JNDI)验证usernamepassword的简单方法。 I've manually added a user in LDAP, and I want to use java to check validate the user's credentials (username and password). 我已经在LDAP中手动添加了一个用户,并且想使用java来检查用户的凭据(用户名和密码)是否有效。

Is this a simple, clear way to do this? 这是一种简单,清晰的方法吗?

Below code I have so far used to connect to LDAP using a bind (which works). 到目前为止,我使用下面的代码使用绑定(有效)连接到LDAP。

package org.jacob.testing;
import java.util.Hashtable;
import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.ldap.LdapContext;


public class jacobLdap {

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

        Hashtable env = new Hashtable();

           env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://localhost:10389");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "uid=admin,ou=system");
        env.put(Context.SECURITY_CREDENTIALS, "secret");


            DirContext ctx = new InitialDirContext(env);
            NamingEnumeration answer = ctx.search("ldap://localhost:10389/ou=users,ou=system","(sn=Herring)",null);

                // I've connected to LDAP, now how should I authenticate a user?

    }

}

The basic idea is that you bind to LDAP as an admin to find the user, then rebind as that user using the password supplied. 基本思想是,您以管理员身份绑定到LDAP来查找用户,然后使用提供的密码将该用户重新绑定为该用户。 If both succeed, the user exists and has that password. 如果两者均成功,则该用户存在并且具有该密码。

Contrary to other answers you may read, you should not attempt to compare the password yourself. 与您可能会阅读的其他答案相反,您不应尝试自己比较密码。 In a correctly set-up LDAP server the password will be hashed, so you would have to reproduce the hashing algorithm yourself etc etc etc. It's pointless and error-prone, and there can be different algorithms per password. 在正确设置的LDAP服务器中,密码将被散列,因此您必须自己等来重现散列算法,等等。它毫无意义且容易出错,每个密码可以有不同的算法。 Make the server do the comparison. 使服务器进行比较。

Conceptually you have two options: 从概念上讲,您有两个选择:

  • bind with "technical" user, then search for user and compare his stored password with the one supplied 与“技术”用户绑定,然后搜索用户并将其存储的密码与提供的密码进行比较
  • use user and password to actually bind to LDAP 使用用户和密码实际绑定到LDAP

In most cases the 2nd approach is preferable because it's simpler and requires less code. 在大多数情况下,第二种方法是更可取的,因为它更简单并且需要更少的代码。 Often the user password isn't even available as an LDAP attribute (eg if you access MS Active Directory over LDAP). 通常,用户密码甚至都不能用作LDAP属性(例如,如果您通过LDAP访问MS Active Directory)。

As hinted by @EJP it may or may not be necessary to bind as admin first for the second approach. 正如@EJP所暗示的那样,对于第二种方法,可能首先必须以管理员身份绑定,也可能没有必要。 If you have small user base there's a fair chance they're all on the same branch of the LDAP tree (eg uid=<user>,ou=users,dc=company,dc=com ). 如果您的用户群很小,那么他们很有可能都位于LDAP树的同一分支上(例如uid=<user>,ou=users,dc=company,dc=com )。 This means you know exactly what DN to use for binding because you simply need to inject the respective user name at a consistent place. 这意味着您确切知道要用于绑定的DN,因为您只需要在一致的位置插入相应的用户名即可。 If you have a large user base, however, users may be distributed across multiple OUs. 但是,如果您的用户群很大,则用户可以分布在多个OU中。 Then you need to bind as admin first and search for the user (ie search for his DN). 然后,您需要首先以admin身份绑定并搜索用户(即搜索其DN)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM