#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]

Padrão
#prosa

DevDay 2011


Ei pessoal.

Este é mais um post de divulgação de evento que será realizado em BH.
O DevDay 2011 acontecerá no dia 27/08 na UNA Campus Aimorés e abordará assuntos como:

  • Planejamento e acompanhamento ágil com Team Foundation
  • Qualidade de codificação
  • Windows Azure
  • TDD
  • Novidades do Rails 3.1
  • Programação funcional com C#
  • Evolução do Javascript

A inscrição pode ser feita no site http://devday.devisland.com

Bom evento pra todos 😉

Padrão