Pergunta

Eu estou usando o seguinte código no Windows Vista Ultimate SP1 para consultar o nosso servidor do Active Directory para verificar o nome de usuário ea senha de um usuário em um domínio.

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;
}

o alvo é usando .NET 3.5, e compilada com VS padrão 2.008

Eu estou logado em uma conta de domínio que é um administrador de domínio onde a aplicação está em execução.

O código funciona perfeitamente no Windows XP; mas eu recebo a seguinte exceção quando executá-lo no 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()

Eu tentei mudar os tipos de autenticação, eu não tenho certeza do que está acontecendo.


Veja também : Validar um nome de usuário e senha contra Active Directory?

Foi útil?

Solução

Se você estiver usando NET 3.5 Utilize este código em seu lugar.

Para autenticar um usuário:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);

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

Se você precisa encontrar o usuário R / W atributos para o objeto de fazer isso:

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

Esta é usando o namespace System.DirectoryServices.AccountManagement então você precisa adicioná-lo a suas declarações usando.

Se você precisa converter um objeto UserPrincipal a um objeto DirectoryEntry para trabalhar com código legado que você pode fazer isso:

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

Outras dicas

Descobri que mesmo código flutuando em torno da Internet em vários sites e não funcionou para mim. Steve Evans provavelmente está certo de que se você estiver em .NET 3.5, você não deve usar este código. Mas se você ainda está em .NET 2.0 você pode tentar este para autenticar os seus serviços de anúncios:

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

A primeira linha cria um objeto DirectoryEntry usando domínio, nome de usuário e senha. Ele também define os AuthenticationTypes. Observe como eu estou definindo tanto segura (Kerberos) autenticação e SSL usando o "bit a bit OR" ( '|'). Operador entre os dois parâmetros

A segunda forças de linha do NativeObject de "entrada" para ligar para os serviços de anúncios usando as informações da primeira linha.

Se uma exceção é lançada, em seguida, as credenciais (ou configurações) foram ruins. Se nenhuma exceção, você está autenticado. A mensagem de exceção normalmente indicará o que deu errado.

Este código é muito semelhante ao que você já tem, mas o domínio é usado quando você tem "caminho", e o nome de usuário não é combinado com o domínio. Certifique-se de definir suas AuthenticationTypes corretamente, também. Isso pode fazer ou quebrar a capacidade de autenticar.

Eu descobri-lo de qualquer maneira Se você passar no domínio com o nome de usuário no Vista não funcionam como "domínio \ usuário" tão só de passagem "user" em vez parece funcionar bem - exceto que você tem que estar no mesmo domínio

privs

A ligação ao LDAP requerem elevados (UAC)? Você poderia tentar executar o Visual Studio e / ou o aplicativo como administrador e ver se isso ajuda. Se esse é o problema que você pode sempre adicionar um manifesto para o aplicativo e configurá-lo para exigir elevação, de que maneira ele irá pedir quando um usuário executa-lo.

Não sei por que isso exigiria privs elevadas, mas vale a pena um tiro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top