Domanda

Sto utilizzando il seguente codice su Windows Vista Ultimate SP1 per eseguire una query sul nostro server Active Directory per verificare il nome utente e la password di un utente su un dominio.

public Object IsAuthenticated()
{
    String domainAndUsername = strDomain + "\\" + strUser;
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass);
    SearchResult result;
    try
    {
        //Bind to the native AdsObject to force authentication.         

        DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") };

        search.PropertiesToLoad.Add("givenName"); // First Name                
        search.PropertiesToLoad.Add("sn"); // Last Name
        search.PropertiesToLoad.Add("cn"); // Last Name

        result = search.FindOne();

        if (null == result)
        {
            return null;
        }

        //Update the new path to the user in the directory.
        _path = result.Path;
        _filterAttribute = (String)result.Properties["cn"][0];
    }
    catch (Exception ex)
    {
        return new Exception("Error authenticating user. " + ex.Message);
    }
    return user;
}

la destinazione utilizza .NET 3.5 e compilata con lo standard VS 2008

Ho effettuato l'accesso con un account di dominio che è un amministratore di dominio su cui è in esecuzione l'applicazione.

Il codice funziona perfettamente su Windows XP; ma ottengo la seguente eccezione quando la eseguo su Vista:

System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()

Ho provato a cambiare i tipi di autenticazione, non sono sicuro di cosa stia succedendo.


Vedi anche : Convalida un nome utente e una password in Active Directory?

È stato utile?

Soluzione

Se stai usando .net 3.5 usa questo codice invece.

Per autenticare un utente:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);

using (adContext)
{
     return adContext.ValidateCredentials(UserName, Password);
}

Se è necessario trovare l'utente con attributi R / W sull'oggetto, procedere come segue:

PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal foundUser = 
    UserPrincipal.FindByIdentity(context, "jdoe");

Questo utilizza lo spazio dei nomi System.DirectoryServices.AccountManagement, quindi è necessario aggiungerlo alle istruzioni using.

Se è necessario convertire un oggetto UserPrincipal in un oggetto DirectoryEntry per funzionare con il codice legacy, è possibile farlo:

DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject();

Altri suggerimenti

Ho trovato lo stesso codice fluttuante su Internet su più siti Web e non ha funzionato per me. Steve Evans ha probabilmente ragione nel dire che se sei su .NET 3.5, non dovresti usare questo codice. Ma se SEI ancora su .NET 2.0 puoi provare questo per autenticare i tuoi servizi AD:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, 
   userName, password, 
   AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
object nativeObject = entry.NativeObject;

La prima riga crea un oggetto DirectoryEntry utilizzando dominio, nome utente e password. Imposta inoltre i tipi di autenticazione. Notare come sto impostando sia l'autenticazione sicura (Kerberos) sia SSL utilizzando il "quotally Bitwise OR" ('|') operatore tra i due parametri.

La seconda riga forza l'oggetto Native di " entry " associare ai servizi AD utilizzando le informazioni della prima riga.

Se viene generata un'eccezione, le credenziali (o le impostazioni) erano errate. Se non fa eccezione, sei autenticato. Il messaggio di eccezione di solito indica cosa è andato storto.

Questo codice è abbastanza simile a quello che hai già, ma il dominio viene utilizzato dove hai "percorso" e il nome utente non è combinato con il dominio. Assicurati di impostare correttamente anche i tuoi AuthenticationTypes. Questo può rendere o interrompere la possibilità di autenticare.

L'ho capito comunque Se passi nel dominio con il nome utente su Vista non funziona come " dominio \ utente " quindi basta passare " utente " invece sembra funzionare bene, tranne per il fatto che devi appartenere allo stesso dominio

Il binding a LDAP richiede privilegi elevati (UAC)? Puoi provare a eseguire Visual Studio e / o l'app come amministratore e vedere se questo aiuta. Se questo è il problema, puoi sempre aggiungere un manifest all'applicazione e impostarlo per richiedere l'elevazione, in questo modo verrà richiesto quando un utente lo esegue.

Non sono sicuro del motivo per cui richiederebbe privilegi elevati, ma vale la pena provare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top