595 Stimmen

Einen Benutzernamen und ein Passwort gegen Active Directory validieren?

Wie kann ich einen Benutzernamen und ein Passwort mit Active Directory abgleichen? Ich möchte einfach prüfen, ob ein Benutzername und ein Kennwort korrekt sind.

705voto

marc_s Punkte 701497

Wenn Sie mit .NET 3.5 oder einer neueren Version arbeiten, können Sie die System.DirectoryServices.AccountManagement Namespace und überprüfen Sie einfach Ihre Anmeldedaten:

// create a "principal context" - e.g. your domain (could be machine, too)
using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
{
    // validate the credentials
    bool isValid = pc.ValidateCredentials("myuser", "mypassword");
}

Es ist einfach, es ist zuverlässig, es ist 100% C# verwalteter Code auf Ihrer Seite - was will man mehr? :-)

Lesen Sie hier alles darüber:

Aktualisierung:

Wie in diese andere SO-Frage (und ihre Antworten) gibt es ein Problem damit, dass dieser Aufruf möglicherweise Folgendes zurückgibt True für alte Passwörter eines Benutzers. Seien Sie sich dieses Verhaltens bewusst und seien Sie nicht zu überrascht, wenn dies geschieht :-) (Dank an @MikeGledhill für den Hinweis darauf!)

83voto

Søren Mors Punkte 948

Mehrere der hier vorgestellten Lösungen sind nicht in der Lage, zwischen einem falschen Benutzer/Passwort und einem Passwort, das geändert werden muss, zu unterscheiden. Das lässt sich auf folgende Weise bewerkstelligen:

using System;
using System.DirectoryServices.Protocols;
using System.Net;

namespace ProtocolTest
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                LdapConnection connection = new LdapConnection("ldap.fabrikam.com");
                NetworkCredential credential = new NetworkCredential("user", "password");
                connection.Credential = credential;
                connection.Bind();
                Console.WriteLine("logged in");
            }
            catch (LdapException lexc)
            {
                String error = lexc.ServerErrorMessage;
                Console.WriteLine(lexc);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc);
            }
        }
    }
}

Wenn das Passwort des Benutzers falsch ist oder der Benutzer nicht existiert, enthält der Fehler

"8009030C: LdapErr: DSID-0C0904DC, comment: AcceptSecurityContext error, data 52e, v1db1",

wenn das Passwort des Benutzers geändert werden muss, enthält es

"8009030C: LdapErr: DSID-0C0904DC, comment: AcceptSecurityContext error, data 773, v1db1"

El lexc.ServerErrorMessage Der Datenwert ist eine Hexadezimal-Darstellung des Win32-Fehlercodes. Dies sind dieselben Fehlercodes, die bei einem anderen Aufruf der Win32 LogonUser-API zurückgegeben werden würden. Die folgende Liste fasst eine Reihe gängiger Werte mit Hex- und Dezimalwerten zusammen:

525 user not found (1317)
52e invalid credentials (1326)
530 not permitted to logon at this time (1328)
531 not permitted to logon at this workstation (1329)
532 password expired (1330)
533 account disabled (1331) 
701 account expired (1793)
773 user must reset password (1907)
775 user account locked (1909)

78voto

DiningPhilanderer Punkte 2647

Wir tun dies in unserem Intranet

Sie müssen System.DirectoryServices verwenden;

Hier sind die Grundzüge des Codes

using (DirectoryEntry adsEntry = new DirectoryEntry(path, strAccountId, strPassword))
{
    using (DirectorySearcher adsSearcher = new DirectorySearcher(adsEntry))
    {
        //adsSearcher.Filter = "(&(objectClass=user)(objectCategory=person))";
        adsSearcher.Filter = "(sAMAccountName=" + strAccountId + ")";

        try
        {
            SearchResult adsSearchResult = adsSearcher.FindOne();
            bSucceeded = true;

            strAuthenticatedBy = "Active Directory";
            strError = "User has been authenticated by Active Directory.";
        }
        catch (Exception ex)
        {
            // Failed to authenticate. Most likely it is caused by unknown user
            // id or bad strPassword.
            strError = ex.Message;
        }
        finally
        {
            adsEntry.Close();
        }
    }
}

38voto

Steven A. Lowe Punkte 59247

Sehr einfache Lösung mit DirectoryServices:

using System.DirectoryServices;

//srvr = ldap server, e.g. LDAP://domain.com
//usr = user name
//pwd = user password
public bool IsAuthenticated(string srvr, string usr, string pwd)
{
    bool authenticated = false;

    try
    {
        DirectoryEntry entry = new DirectoryEntry(srvr, usr, pwd);
        object nativeObject = entry.NativeObject;
        authenticated = true;
    }
    catch (DirectoryServicesCOMException cex)
    {
        //not authenticated; reason why is in cex
    }
    catch (Exception ex)
    {
        //not authenticated due to some other exception [this is optional]
    }

    return authenticated;
}

der NativeObject-Zugriff ist erforderlich, um einen falschen Benutzer/Passwort zu erkennen

29voto

Alan Punkte 44139

Leider gibt es keine "einfache" Möglichkeit, die Anmeldedaten eines Benutzers im AD zu überprüfen.

Bei jeder bisher vorgestellten Methode kann es zu einem falsch-negativen Ergebnis kommen: Die Anmeldedaten eines Benutzers sind zwar gültig, aber AD gibt unter bestimmten Umständen falsch zurück:

  • Der Benutzer muss bei der nächsten Anmeldung sein Passwort ändern.
  • Das Passwort des Benutzers ist abgelaufen.

ActiveDirectory erlaubt es Ihnen nicht, LDAP zu verwenden, um festzustellen, ob ein Kennwort ungültig ist, weil ein Benutzer sein Kennwort ändern muss oder weil sein Kennwort abgelaufen ist.

Um festzustellen, ob das Passwort geändert wurde oder abgelaufen ist, können Sie Win32:LogonUser() aufrufen und den Windows-Fehlercode auf die folgenden 2 Konstanten überprüfen:

  • ERROR_PASSWORD_MUST_CHANGE = 1907
  • ERROR_PASSWORD_EXPIRED = 1330

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X