LdapConnection.bind()在提供有效凭据时抛出INVALID_CREDENTIALS

时间:2011-02-02 02:24:11

标签: asp.net authentication ldap

我在大约三年内第一次开展ASP.NET项目;与此同时,我一直在使用Python / Django,PHP和Obj-C。无论如何,直接把它捡起来......除了现在完全杀了我的东西,我有一种感觉它一定是盯着我的脸:

我正在尝试绑定到LDAP服务器,以便对用户进行身份验证。它在这里工作的方式是,绑定您自己的凭据,使用它来查找您正在进行身份验证的用户的专有名称,然后再次绑定他们的DN和密码。如果绑定成功,则密码正确并且可以对用户进行身份验证。

这是问题 - 第一个绑定(在固定凭据上,能够搜索用户及其子树的那个)工作正常。搜索工作正常。无论如何,第二个绑定失败,LDAP错误为INVALID_CREDENTIALS。即使提供完全有效的凭据,也会发生这种情况。

这是代码,当然还有用户名和密码编辑......

public static bool Authenticate(string username, string password)  
{  
    bool valid = false;  

    try  
    {  
        LdapDirectoryIdentifier lid = new LdapDirectoryIdentifier("[[REDACTED]]");  
        System.Net.NetworkCredential cred = new System.Net.NetworkCredential("[[REDACTED]]", "[[REDACTED]]");  

        LdapConnection lconn = new LdapConnection(lid);  
        lconn.Bind(cred);  
        SearchRequest request = new SearchRequest("[[REDACTED]]", "cn=" + username, SearchScope.Subtree, new String[] { "dn", "sn" });  
        SearchResponse response = (SearchResponse)lconn.SendRequest(request);  

        SearchResultEntry rslt = response.Entries[0];  
        string userdn = rslt.DistinguishedName;  
        System.Net.NetworkCredential usercred = new System.Net.NetworkCredential(userdn, password);  
        //we're already in try/catch, so if this fails we'll be booted out  
        lconn.Bind(usercred);  
        //otherwise we're all good  
        valid = true;  
    }  
    catch (LdapException e)  
    {  
        if (e.ErrorCode == 0x31) //INVALID_CREDENTIALS  
            throw (e);  
        //otherwise fall through to DB authentication  
    }  

//DB Auth goes here  

    return valid;  

}  

我已经跨过这段代码,读出变量并手动执行LDAP绑定(通过python控制台中的python-ldap),DN /密码组合工作正常。出了什么问题?

1 个答案:

答案 0 :(得分:1)

来自另一个SO post。如果要使用DN进行重新绑定,则需要使用AuthType.Basic

您可能还想在using周围使用LdapConnection,这样您就不会忘记关闭LdapConnection

以下是应该有效的更新代码。当然,您最好在LDAP服务器上启用SSL,因为使用了基本身份验证。

public static bool Authenticate(string username, string password)  
{  
    bool valid = false;  

    try  
    {  
        LdapDirectoryIdentifier lid = new LdapDirectoryIdentifier("[[REDACTED]]");  
        System.Net.NetworkCredential cred = new System.Net.NetworkCredential("[[REDACTED]]", "[[REDACTED]]");  

        string userdn;
        using (LdapConnection lconn = new LdapConnection(lid))
        {
            lconn.Bind(cred);  
            SearchRequest request = new SearchRequest("[[REDACTED]]", "cn=" + username, SearchScope.Subtree, new String[] { "dn", "sn" });  
            SearchResponse response = (SearchResponse)lconn.SendRequest(request);  

            SearchResultEntry rslt = response.Entries[0];  
            userdn = rslt.DistinguishedName;  
        }

        System.Net.NetworkCredential usercred = new System.Net.NetworkCredential(userdn, password);  
        using (LdapConnection lconn2 = new LdapConnection(lid))
        {
            lconn2.AuthType = AuthType.Basic;
            //we're already in try/catch, so if this fails we'll be booted out  
            lconn2.Bind(usercred);
            //otherwise we're all good  
            valid = true;  
        }
    }  
    catch (LdapException e)  
    {  
        if (e.ErrorCode == 0x31) //INVALID_CREDENTIALS  
            throw (e);  
        //otherwise fall through to DB authentication  
    }  

//DB Auth goes here  

    return valid;  

}