How do I validate Active Directory creds over LDAP + SSL?

前端 未结 4 923
一个人的身影
一个人的身影 2020-12-02 13:46

I\'m trying to use the .NET 3.5 System.DirectoryServices.AccountManagement namespace to validate user credentials against our Active Directory LDAP server

相关标签:
4条回答
  • 2020-12-02 14:13

    Maybe this is another way. There's nothing unusual in validate credentials. The ContextOptions must set properly.

    Default value:

    ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing

    Add Ssl:

    ContextOptions.Negotiate | ContextOptions.Signing | ContextOptions.Sealing | ContextOptions.SecureSocketLayer

    ContextOptions.Negotiate or ContextOptions.SimpleBind is required. Or whatever your server need to perform authentication. ContextOptions only supports OR bit to bit.

    You could try also set the ContextOptions directly this way in ValidateCredentials method.

    using (var pc = new PrincipalContext(ContextType.Domain, "sd.example.com:636", "DC=sd,DC=example,DC=com", ContextOptions.Negotiate | ContextOptions.SecureSocketLayer))
    {
        return pc.ValidateCredentials(_username, _password);
    }
    

    Or

    using (var pc = new PrincipalContext(ContextType.Domain, "sd.example.com:636", "DC=sd,DC=example,DC=com", ContextOptions.Negotiate))
    {
        return pc.ValidateCredentials(_username, _password, ContextOptions.Negotiate | ContextOptions.SecureSocketLayer);
    }
    
    0 讨论(0)
  • 2020-12-02 14:17

    I know this is old, but for anybody running into this again:

    PrincipalContext.ValidateCredentials(...), by default, tries to open an SSL connection (ldap_init(NULL, 636)) followed by setting the option LDAP_OPT_FAST_CONCURRENT_BIND.

    If a (trusted?) client certificate is present, however, the LDAP connection is implicitly bound and fast bind cannot be enabled anymore. PrincipalContext doesn't consider this case and fails with an unexpected DirectoryOperationException.

    Workaround: To support SSL where possible, but have a fallback, call ValidateCredentials(...) with default options first (i.e. no options). If this fails with the DirectoryOperationException, try again by specifying the ContextOptions (Negotiate | Sealing | Signing), which is what ValidateCredentials internally does for the expected LdapException anyway.

    0 讨论(0)
  • 2020-12-02 14:21

    I was able to validate credentials using the System.DirectoryServices.Protocols namespace, thanks to a co-worker. Here's the code:

    // See http://support.microsoft.com/kb/218185 for full list of LDAP error codes
    const int ldapErrorInvalidCredentials = 0x31;
    
    const string server = "sd.example.com:636";
    const string domain = "sd.example.com";
    
    try
    {
        using (var ldapConnection = new LdapConnection(server))
        {
            var networkCredential = new NetworkCredential(_username, _password, domain);
            ldapConnection.SessionOptions.SecureSocketLayer = true;
            ldapConnection.AuthType = AuthType.Negotiate;
            ldapConnection.Bind(networkCredential);
        }
    
        // If the bind succeeds, the credentials are valid
        return true;
    }
    catch (LdapException ldapException)
    {
        // Invalid credentials throw an exception with a specific error code
        if (ldapException.ErrorCode.Equals(ldapErrorInvalidCredentials))
        {
            return false;
        }
    
        throw;
    }
    

    I'm not thrilled with using a try/catch block to control decisioning logic, but it's what works. :/

    0 讨论(0)
  • 2020-12-02 14:25

    For me, the ValidateCredentials method works just fine. The problem, I found, was on the server hosting the AD (I'm using AD LDS). You needed to associate the server certificate with the AD instance. So if your instance was called 'MyAD' (or ActiveDirectoryWebService), you needed to open up the MMC, snap in the 'Certificates' module, select 'Service Account' and then select 'MyAD' from the list. From there you can add the SSL certificate into the 'MyAD' Personal store. This finally kicked the SSL processing into gear.

    I suspect, from what I know of the LdapConnection method and the fact that you omitted the callback function, that you are not validating your server certificate. It's a messy job and ValidateCredentials does it for free. Probably not a big deal, but a security hole none-the-less.

    0 讨论(0)
提交回复
热议问题