Set callback for System.DirectoryServices.DirectoryEntry to handle self-signed SSL certificate?

后端 未结 3 1437
谎友^
谎友^ 2020-12-01 22:26

I have an application replicating data from a directory service using typical System.DirectoryServices.DirectoryEntry code. I now have a requirement to replicate from Novell

3条回答
  •  被撕碎了的回忆
    2020-12-01 23:07

    I promise, this will be my last post on this particular question. :)

    After another week of research and development, I have a nice solution to this, and it has worked exceedingly well for me thus far.

    The approach is somewhat different then my first answer, but in general, it's the same concept; using the LdapConnection to force validation of the certificate.

    //I set my Domain, Filter, and Root-AutoDiscovery variables from the config file
    string Domain = config.LdapAuth.LdapDomain;
    string Filter = config.LdapAuth.LdapFilter;
    bool AutoRootDiscovery = Convert.ToBoolean(config.LdapAuth.LdapAutoRootDiscovery);
    
    //I start off by defining a string array for the attributes I want 
    //to retrieve for the user, this is also defined in a config file.
    string[] AttributeList = config.LdapAuth.LdapPropertyList.Split('|');
    
    //Delcare your Network Credential with Username, Password, and the Domain
    var credentials = new NetworkCredential(Username, Password, Domain);
    
    //Here I create my directory identifier and connection, since I'm working 
    //with a host address, I set the 3rd parameter (IsFQDNS) to false
    var ldapidentifier = new LdapDirectoryIdentifier(ServerName, Port, false, false);
    var ldapconn = new LdapConnection(ldapidentifier, credentials);
    
    //This is still very important if the server has a self signed cert, a certificate 
    //that has an invalid cert path, or hasn't been issued by a root certificate authority. 
    ldapconn.SessionOptions.VerifyServerCertificate += delegate { return true; };
    
    //I use a boolean to toggle weather or not I want to automatically find and query the absolute root. 
    //If not, I'll just use the Domain value we already have from the config.
    if (AutoRootDiscovery)
    {
        var getRootRequest = new SearchRequest(string.Empty, "objectClass=*", SearchScope.Base, "rootDomainNamingContext");
        var rootResponse = (SearchResponse)ldapconn.SendRequest(getRootRequest);
        Domain = rootResponse.Entries[0].Attributes["rootDomainNamingContext"][0].ToString();
    }
    
    //This is the filter I've been using : (&(objectCategory=person)(objectClass=user)(&(sAMAccountName={{UserName}})))
    string ldapFilter = Filter.Replace("{{UserName}}", UserName);
    
    //Now we can start building our search request
    var getUserRequest = new SearchRequest(Domain, ldapFilter, SearchScope.Subtree, AttributeList);
    
    //I only want one entry, so I set the size limit to one
    getUserRequest.SizeLimit = 1;
    
    //This is absolutely crucial in getting the request speed we need (milliseconds), as
    //setting the DomainScope will suppress any refferal creation from happening during the search
    SearchOptionsControl SearchControl = new SearchOptionsControl(SearchOption.DomainScope);
    getUserRequest.Controls.Add(SearchControl);
    
    //This happens incredibly fast, even with massive Active Directory structures
    var userResponse = (SearchResponse)ldapconn.SendRequest(getUserRequest);
    
    //Now, I have an object that operates very similarly to DirectoryEntry, mission accomplished  
    SearchResultEntry ResultEntry = userResponse.Entries[0];
    

    The other thing I wanted to note here is that SearchResultEntry will return user "attributes" instead of "properties".

    Attributes are returned as byte arrays, so you have to encode those in order to get the string representation. Thankfully, System.Text.Encoding contains a native ASCIIEncoding class that can handle this very easily.

    string PropValue = ASCIIEncoding.ASCII.GetString(PropertyValueByteArray);
    

    And that's about it! Very happy to finally have this figured out.

    Cheers!

提交回复
热议问题