12

Ich habe eine MVC-Anwendung, die sich anmelden und einen Benutzer gegen Active Directory verifizieren muss. Ich verwende die PrincipalContext.ValidateCredentials Methode, bekomme aber immer eine Authentifizierung von false.PrincipalContext.ValidateCredentials gibt immer FALSE zurück

Verbindung mit dem Server ist in Ordnung. Das Problem scheint in der ValidateCredentials auftreten.

Hier ist mein Code:

public static bool IsAuthenticated(string domain, string username, string pwd) { 
    bool IsAuthenticated = false; 

    try { 
     PrincipalContext insPrincipalContext = 
      new PrincipalContext(ContextType.Domain, domain, "DC=c1w,DC=com"); 

     username = "c1w\\" + username; 

     IsAuthenticated = insPrincipalContext.ValidateCredentials(username, pwd); 
    } 
    catch (Exception ex) 
    { 
     // Rethrow this exception 
     ExceptionPolicy.HandleException(ex, "Exception Policy"); 
    } 

    return IsAuthenticated; 
} 

Wer weiß, warum dies geschehen würde?

Antwort

7

Ich sehe nicht, wo Sie die Variable "pwd" initialisieren Vielleicht sollten Sie ContextOption in dieser Methode verwenden, um genau das erforderliche Verhalten anzugeben. Sorry für zu breite Antwort, aber es gibt nicht viele Details in Ihrer Frage

+0

Editierte die Frage, um die gesamte Methode einzuschließen. Werde den ContextOption-Vorschlag ausprobieren. Vielen Dank. –

+5

B-Rain, Die ContextOption-Referenz wies mich in die richtige Richtung. Es wurde mit den ContextOptions.Negotiate für meinen Aufruf von AD und ContextOptions.SimpleBind für die Validierungsberechtigungsnachweise beendet. Simple Bind wird für mich funktionieren, da die Site SSL Secured sein wird. Danke für Ihre Hilfe. –

+0

Upvoted sowohl die Frage als auch die Antwort, weil dies mir auch in meiner Situation geholfen hat. In meinem Fall befindet sich mein Dev-Computer (wo Login ohne Kontext angegeben ist) in der gesicherten Zone im Netzwerk, aber der Webserver (wo Login funktioniert nicht ohne Kontext angegeben) ist in der DMZ. Ich verwendete die gleiche Konfiguration wie @Billy Logan - Verhandeln Sie über den Aufruf von AD und SimpleBind über den Validierungsaufruf. – arootbeer

1

Es scheint, dass Sie den Benutzer mit Domäne \ Benutzername Format validieren. Möglicherweise möchten Sie den Domänennamen von userName analysieren und den ValidateCredential-Benutzer verwenden.

12

So funktioniert ValidateCredentials(string, string): Zuerst versucht es, mit den Negotiate, Signing und Sealing Kontextoptionen zu authentifizieren. Wenn dies fehlschlägt, versucht es erneut mit SimpleBind und SecureSocketLayer.

Das Problem ist, dass das NT4 (AKA "Legacy", AKA "Down-Level-Name") -Format (DOMAIN\UserName, oder richtiger, NetBiosName\SamAccountName) nicht mit Negotiate funktioniert. Aber es funktioniert mit SimpleBind.

Also, was wohl passiert, wenn die 2-Parameter ValidateCredentials() Methode aufrufen, ist, dass es zunächst fehl verhandeln, weil es nicht die NT4-Format nicht mag, und dann wieder schlägt fehl, wenn einfache Bindung verwenden.

Während meiner eigenen Tests habe ich festgestellt, dass der Grund, warum es auch nach dem Zurückfallen auf die Verwendung der einfachen Bindung fehlschlägt, ist, dass es nicht nur SimpleBind verwendet. Es verwendet SimpleBind plus SecureSocketLayer. Dies bedeutet, dass es weiterhin fehlschlägt, wenn der Active Directory-Server nicht ordnungsgemäß für die Verwendung von SSL eingerichtet ist (ein häufiges Szenario für Testumgebungen).

Wie in einem der Kommentare erwähnt, wollen Sie nie, SimpleBind von selbst (ohne SecureSocketLayer) verwenden, sonst werden Ihre Kennwörter über das Netzwerk im Klartext gesendet.

In der freien Wildbahn habe ich gesehen, dass einige Active Directory-Systeme die Verwendung von einfachen Bindungen überhaupt nicht zulassen, so dass Sie es mit Negotiate arbeiten müssen.

Ich habe 2 Wege gefunden, um dieses Problem zu umgehen:

1) Wenn alles auf dem gleichen Gebiet geschieht, sollten Sie in der Lage sein ValidateCredentials zu nennen nur mit dem Benutzernamen (SAM Account-Name), das Weglassen der Teil "DOMAIN". Dann wird es beim ersten Mal mit Negotiate richtig funktionieren.

2) Wenn der Domain-Teil ist wichtig, weil es beteiligt mehrere Domänen sein kann (das heißt Domain1\UserA und Domain2\UserA sind verschiedene Menschen), dann ist es etwas komplizierter wird. In diesem Fall übersetzte ich den NT4-Namen (DOMAIN \ User) in das Format "User Principal Name" (z. B. [email protected]). Es gibt ein paar verschiedene Möglichkeiten, dies zu tun.Am einfachsten ist es wahrscheinlich, die 3-Parameter-Überladung von UserPrincipal.FindByIdentity() zu verwenden und dann den Wert der UserPrincipalName-Eigenschaft auf das Ergebnis zu ziehen. Ein anderer Weg wäre, eine DirectorySearcher zu verwenden und LDAP://domain für die 10 Eigenschaft des Benutzers mit dem übereinstimmenden sAMAccountName Wert abzufragen. Hinweis: Diese Lösung funktioniert nur, wenn sich alle beteiligten Domänen in derselben Gesamtstruktur befinden.