#desenvolvimento

C# – Como obter o usuário logado no AD?


Olá pessoal.

Não é novidade precisar capturar alguns dados diretamente do Active Directory através do usuário logado, sem que seja necessário a realização de uma nova autenticação. Eu já tinha feito isto uma vez utilizando Java e achei bem trabalhoso, pensei então que em C# seria mais natural acreditando em uma possível integração da plataforma .NET.

Comecei a pesquisar sobre uma melhor forma para fazer isto, e não encontrei muitas alternativas. De qualquer forma irei postar uma solução aqui, deixando os comentários sempre abertos para que outras soluções possam ser compartilhadas.

Para começar adicione as referências System.DirectoryServices e System.DirectoryServices.AccountManagement ao seu projeto.

Com isto é possível utilizar os namespaces que possuem as classes associadas ao Active Directory:

using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

O método abaixo cria os objetos das classes referentes ao Active Directory necessários para a busca dos dados do usuário logado.

private Usuario ObterDadosUsuarioLogado()
{
   // Obtém o login do usuário na rede.
   string loginUserNetwork = Page.User.Identity.Name.Split('\\')[1];

   // Cria um contexto principal para definir a busca na base do AD.
   PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);

   // Cria uma query do Active Directory Domain Services.
   DirectorySearcher directorySearcher = new DirectorySearcher(principalContext.ConnectedServer);

   // Cria um filtro para a busca com o login do usuário da rede.
   directorySearcher.Filter = "(sAMAccountName=" + loginUserNetwork + ")";

   /*
    * Cria um elemento da hierarquia do Active Directory.
    * Este elemento é retornado durante uma busca através de DirectorySearcher.
    */
   SearchResult searchResult = directorySearcher.FindOne();

   // Cria um objeto encapsulado da hierarquia de diretório serviços do AD.
   DirectoryEntry directoryEntry = searchResult.GetDirectoryEntry();

   // Cria um usuário.
   return new Usuario(directoryEntry);
}

Os atributos do Active Directory possuem uma nomenclatura pouco inteligível, por isto resolvi criar uma classe denominada Usuario e mapear alguns atributos do AD como propriedades da classe. E para facilitar criei um construtor que recebe uma coleção de atributos do AD e associa às propriedades do usuário:

public Usuario(DirectoryEntry directoryEntry)
{
   // Obtém as informações do usuário.
   FirstName = directoryEntry.Properties["givenName"][0].ToString();
   LastName = directoryEntry.Properties["sn"][0].ToString();
   DisplayName = directoryEntry.Properties["displayName"][0].ToString();
   Description = directoryEntry.Properties["description"][0].ToString();

   // Obtém as informações da conta do usuário.
   UserPrincipalName = directoryEntry.Properties["userPrincipalName"][0].ToString();
   LogonName = directoryEntry.Properties["sAMAccountName"][0].ToString();
   ScriptPath = directoryEntry.Properties["scriptPath"][0].ToString();

   // Obtém as informações referentes às funções do usuário.
   Title = directoryEntry.Properties["title"][0].ToString();
   Department = directoryEntry.Properties["department"][0].ToString();
   Company = directoryEntry.Properties["company"][0].ToString();
   Manager = directoryEntry.Properties["manager"][0].ToString().Split(',')[0].Split('=')[1];

   // Obtém as informações referente aos contatos do usuário.
   TelephoneNumber = directoryEntry.Properties["telephoneNumber"][0].ToString();
   FaxNumber = directoryEntry.Properties["facsimileTelephoneNumber"][0].ToString();
   Email = directoryEntry.Properties["mail"][0].ToString();

   // Obtém as as informações referentes ao endereço do usuário.
   StreetAddress = directoryEntry.Properties["streetAddress"][0].ToString();
   City = directoryEntry.Properties["l"][0].ToString();
   State = directoryEntry.Properties["st"][0].ToString();
   Zip = directoryEntry.Properties["postalCode"][0].ToString();
   Country = directoryEntry.Properties["co"][0].ToString();
}

Esta foi a forma mais simples que encontrei para acessar os dados. Compartilho os links que me ajudaram a chegar nesta solução:

How to get userdetails from Active Directory based on username using ASP.NET

All Operations on Active Directory (AD) using C#

Até breve 😉

[Editado]

O leitor Hugo, encontrou uma dificuldade para obter o usuário e compartilhou o código que acrescentou no arquivo web.config. Eu solicitei que ele disponibilizasse o código para que possa ajudar, se mais alguém tiver o mesmo problema. Obrigada, Hugo.


<!--
   <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.<wbr />aspx" timeout="2880" />
   </authentication>
-->
<authentication mode="Windows" />
<!--
   Then add the authorization tag to deny access to anonymous users.
   If the users are using Internet Explorer and are connecting from an Intranet zone, IE automatically will login the user. 
   But if the user is connecting from the Internet zone, IE will still display a login box though for safety.
   But these are options that can be set from IE.
-->
<authorization>
   <deny users="?" />
</authorization>

[/Editado]

Anúncios
Padrão

16 comentários sobre “C# – Como obter o usuário logado no AD?

  1. Fabio Souza disse:

    Ola Pessoal,

    Estou precisando de uma ajuda, será que é possível identificar se o usuário está logado ou não em uma maquina
    e se consigo tirar alguma informação da maquina que o mesmo se encontra (IP, MAC ou HOST)?

  2. Anderson disse:

    Muito bom o post, é oq eu preciso, porem na plataforma Windows Form, o comando “Page” não reconhece nessa plataforma, pode me ajudar?

    • Olá Anderson,

      Atualmente eu não tenho o ambiente de C# configurado para poder lhe ajudar melhor. A classe Page seria quase que o equivalente a classe Form, mas eu não sei lhe falar com certeza quais métodos você poderia utilizar 😦
      Espero que tenha sucesso por ai.

      Até breve.

  3. Hugo Agostinho disse:

    Brena,

    Obrigado pelas dicas e sugestões.

    No ficheiro web.config tive que efectuar as seguintes alterações:

    <!–

    –>

    _______________________________________________________________________________

    No método: private Usuario ObterDadosUsuarioLogado()
    tive que alterar a seguinte linha:
    // Cria um filtro para a busca com o login do usuário da rede.
    directorySearcher.Filter = “(sAMAccountName=” + loginUserNetwork[1] + “)”;

    Vou agora completar o código com a classe Usuario.

    Muito obrigado pela ajuda que deu até agora

    • Hugo,

      Fico feliz em saber que está conseguindo evoluir no código.
      O trecho de código que você acrescentou no web.config não pode ser exibido nos comentários. Caso queira, me envie por e-mail para que eu possa acrescentá-lo no post.

      Obrigada.

  4. Hugo Agostinho disse:

    o resultado do seu IF é:
    loginUserNetwork = “Usuário não autenticado”;

    mas é estranho porque quando ligo o PC tenho que colocar dominio\username e password, ou seja, já me encontro autenticado no dominio

  5. Hugo Agostinho disse:

    Olá novamente :/

    Continuo com problemas :(…

    Estou a desenvolver numa máquina com S.O Windows 7 enterprise que está autenticada a um dominio e sempre me pareceu que o seu exemplo era exactamente o que eu necessitava.

    Quando executo no Visual Studio, não retorna o loginUserNetwork

    string [] loginUserNetwork = Page.User.Identity.Name.Split(‘\\’);
    loginUserNetwork[0] retorna “” -> Vazio

    No browser retorna:

    Server Error in ‘/’ Application.
    ——————————————————————————–

    Object reference not set to an instance of an object.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error:

    Line 39:
    Line 40: // Cria um objeto encapsulado da hierarquia de diretório serviços do AD.
    Line 41: DirectoryEntry directoryEntry = searchResult.GetDirectoryEntry();
    __________________________________________________________________________________

    Será que necessito efectuar alguma acções sobe o IIS ?

    Obrigado
    Hugo

    • Hugo,

      Troque o código:

      string [] loginUserNetwork = Page.User.Identity.Name.Split(‘\\’);
      

      Por:

      string loginUserNetwork = string;empty;
      if (User.Identity.IsAuthenticated)
      {
         loginUserNetwork = User.Identity.Name;
      }
      else
      {
         loginUserNetwork = "Usuário não autenticado";
      }
      

      E poste qual retorno obteve.
      Aguardo.

  6. Hugo Agostinho disse:

    Estive a utilizar o código em C# que disponibilizou sobre autenticação na AD e deparei-me com algumas questões. Em primeiro lugar reparei que apenas o bloco de código disponibilizado não é suficiente pois seria, talvez, necessário declarar mais algumas classes (de acordo com os erros devolvidos pelo VS2010). No código que enviei por email tem montes de errors, o que é que faltará ? Poder-me-ia ajudar, se faz favor

    Obrigado

    • Hugo,

      O código do post foi feito utilizando um projeto web, então após criar um projeto web crie também uma página ASPX e adicione o método ObterDadosUsuarioLogado() no arquivo *.aspx.cs.

      Você também precisa criar uma classe C# denominada Usuario e dentro desta classe adicione o método construtor chamado Usuario.

      Além disso, você vai precisar criar as propriedades do usuário que estão recebendo os valores vindos do AD conforme o exemplo abaixo:

      public string FirstName { get; set; }
      

      Qualquer dúvida é só postar 😉

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s