LDAP:如何使用连接详细信息验证用户身份

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LDAP:如何使用连接详细信息验证用户身份相关的知识,希望对你有一定的参考价值。

我无法使用LDAP对用户进行身份验证。我有以下细节:

URL=ldap://10.10.10.10:389 
LDAP BASE:DC=lab2,DC=ins 
LDAP Bind Account: CN=Ldap Bind,OU=Service Accounts,OU=TECH,DC=lab2,DC=ins 
LDAP Bind Account Pw: secret 

我可以使用上面的详细信息搜索sAMAccountName值,但是如何使用用户名和密码验证用户? 如果您按照我之前的问题进行操作,那么您将了解到,我已成功连接到LDAP服务器但无法对其进行身份验证。 用户进行身份验证:

user: someusername
password: somepwd

我无法使用'somepwd'连接到LDAP服务器,我应该如何使用someusername。我能够将给定的用户搜索为sAMAccountName

答案

这是我在各个地方找到的东西的混搭。如果您不想使用UnboundID SDK,它应该让您沿着正确的路径前进。这不是生产质量,如果您的商店支持,您可能希望在此处添加SSL内容。

public static Boolean validateLogin(String userName, String userPassword) {
    Hashtable<String, String> env = new Hashtable<String, String>();


    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);

    // To get rid of the PartialResultException when using Active Directory
    env.put(Context.REFERRAL, "follow");

    // Needed for the Bind (User Authorized to Query the LDAP server) 
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, LDAP_BIND_DN);
    env.put(Context.SECURITY_CREDENTIALS, LDAP_BIND_PASSWORD);

    DirContext ctx;
    try {
       ctx = new InitialDirContext(env);
    } catch (NamingException e) {
       throw new RuntimeException(e);
    }

    NamingEnumeration<SearchResult> results = null;

    try {
       SearchControls controls = new SearchControls();
       controls.setSearchScope(SearchControls.SUBTREE_SCOPE); // Search Entire Subtree
       controls.setCountLimit(1);   //Sets the maximum number of entries to be returned as a result of the search
       controls.setTimeLimit(5000); // Sets the time limit of these SearchControls in milliseconds

       String searchString = "(&(objectCategory=user)(sAMAccountName=" + userName + "))";

       results = ctx.search("", searchString, controls);

       if (results.hasMore()) {

           SearchResult result = (SearchResult) results.next();
           Attributes attrs = result.getAttributes();
           Attribute dnAttr = attrs.get("distinguishedName");
           String dn = (String) dnAttr.get();

           // User Exists, Validate the Password

           env.put(Context.SECURITY_PRINCIPAL, dn);
           env.put(Context.SECURITY_CREDENTIALS, userPassword);

           new InitialDirContext(env); // Exception will be thrown on Invalid case
           return true;
       } 
       else 
           return false;

    } catch (AuthenticationException e) { // Invalid Login

        return false;
    } catch (NameNotFoundException e) { // The base context was not found.

        return false;
    } catch (SizeLimitExceededException e) {
        throw new RuntimeException("LDAP Query Limit Exceeded, adjust the query to bring back less records", e);
    } catch (NamingException e) {
       throw new RuntimeException(e);
    } finally {

       if (results != null) {
          try { results.close(); } catch (Exception e) { /* Do Nothing */ }
       }

       if (ctx != null) {
          try { ctx.close(); } catch (Exception e) { /* Do Nothing */ }
       }
    }
}
另一答案

LDAP连接以anonymous开头。要更改连接的授权状态,请使用BIND请求。 BIND请求采用两种形式,“简单”或“SASL”。 “简单”BIND请求采用可分辨的名称和密码。 BIND请求应通过安全连接传输,或使用StartTLS扩展请求提升为安全连接的非安全连接。

使用UnboundID LDAP SDK:

// exception handling not shown
LDAPConnection ldapConnection = new LDAPConnection(hostname,port);
BindRequest bindRequest = new SimpleBindRequest(username,password);
BindResult bindResult = ldapConnection.bind(bindRequest);
if(bindResult.getResultCode().equals(ResultCode.SUCCESS)) {
   /// successful authentication
}
ldapConnection.close();
另一答案

We have several JNDI Samples这可能会有所帮助。

另一答案

尝试使用它,它对我有用

public static Boolean validateLogin(String userName, String userPassword) {
    Hashtable<String, String> env = new Hashtable<String, String>();


    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://" + LDAP_SERVER + ":" + LDAP_SERVER_PORT + "/" + LDAP_BASE_DN);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, userName + "@" + LDAP_SERVER);
    env.put(Context.SECURITY_CREDENTIALS, userPassword);

    DirContext ctx;
    try {
       ctx = new InitialDirContext(env); //throw exception, if username-password not correct
       return true;
    } catch (Exception e) {
        return false;
    }
}

以上是关于LDAP:如何使用连接详细信息验证用户身份的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Boot/Spring Security 对 LDAP 进行证书身份验证

CAS 身份验证后在 JSF 托管 Bean 中获取 LDAP 属性

CAS认证后在JSF Managed Bean中获取LDAP属性

LDAP 身份验证超时

如何使用 xml 配置文件、JAVA、Spring 安全性对 LDAP 用户进行身份验证

MarkLogic LDAP身份验证