Ich verspreche, dies wird mein letzter Beitrag zu dieser speziellen Frage sein. :)
Nach einer weiteren Woche der Forschung und Entwicklung, habe ich eine schöne Lösung für diese, und es hat bis jetzt außerordentlich gut für mich gearbeitet.
Der Ansatz ist etwas anders als meine erste Antwort, aber im Allgemeinen ist es das gleiche Konzept; Verwenden der LdapConnection, um die Validierung des Zertifikats zu erzwingen.
//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];
Das andere, was ich wollte hier zu beachten ist, dass SearchResultEntry Benutzer zurückkehren wird „Attribute“ anstelle von „Eigenschaften“.
Attribute werden als Bytearrays zurückgegeben, daher müssen Sie diese codieren, um die Zeichenfolgendarstellung zu erhalten. Zum Glück enthält System.Text.Encoding eine native ASCIIEncoding-Klasse, die das sehr einfach handhaben kann.
string PropValue = ASCIIEncoding.ASCII.GetString(PropertyValueByteArray);
Und das war's! Sehr glücklich, das endlich herausgefunden zu haben.
Prost!
Hallo. Danke für die Eingabe, sehr geschätzt. Ich komme auch zu der Schlussfolgerung, dass das ganze Problem viel zuverlässiger mit dem Protokoll-Namespace der niedrigeren Ebene angegangen werden könnte. Was ich bemerkt habe, ist, dass, wenn das selbstsignierte Zertifikat korrekt zum Zertifikatspeicher des lokalen Computers hinzugefügt wurde, ich den Callover von VerifyServerCertificate setzen kann, um das Cert erfolgreich zu validieren, etwa "delegate (LdapConnection-Verbindung, X509Certificate-Zertifikat) {return new X509Certificate2 (Zertifikat) .Verify()} ", aber ich habe immer noch keine Freude mit DirectoryEntry. – Andrew
Ich habe auch bemerkt, dass ich in meinen Systemereignissen während fehlgeschlagener DirectoryEntry-Versuche Folgendes bekomme: "Das vom Remote-Server empfangene Zertifikat enthält nicht den erwarteten Namen. Es ist daher nicht möglich festzustellen, ob wir eine Verbindung zum richtigen Server herstellen. Der Servername, den wir erwartet haben, lautet MYSERVER.MYDOMAIN.CO.UK. Die SSL-Verbindungsanforderung ist fehlgeschlagen. Die angehängten Daten enthalten das Serverzertifikat. " Ich untersuche das jetzt, aber ich denke, die Antwort ist immer noch der Namespace von Protocols für maximales Vertrauen und reduzierte Umweltabhängigkeit. – Andrew
Andrew, danke für den Kommentar. Es scheint, dass wir auf ein sehr ähnliches Ziel hinarbeiten. Dieser Fehler, der bei Systemereignissen auftritt, stimmt mit vielen Informationen überein, die ich im Internet gelesen habe, wem das Zertifikat ausgestellt wurde. Viele der Server, auf denen SSL ausgeführt wird, mit denen ich zu interagieren versuche, verfügen über ein Zertifikat, das an eine andere Domäne als die, an die ich in der LdapConnection binde, gesendet wird ... und dies führt sicherlich dazu, dass DirectoryEntry fehlschlägt. – X3074861X