 .NET
- Acessando o Active Directory
.NET
- Acessando o Active Directory 
Antes de iniciar o artigo é bom rever alguns conceitos básicos como Active Directory, LDAP, domínio,etc. Vamos lá...
O Active Directory (AD) é uma implementação de serviço de diretório no protocolo LDAP (Lightweight Directory Access Protocol) que armazena informações sobre objetos em uma rede e disponibiliza essas informações a usuários e administradores desta rede. (Pense no AD como um banco de dados hierárquico orientado a objetos que representa todos os seus recursos de rede.)
O LDAP é um protocolo para atualizar e pesquisar diretórios rodando sobre TCP/IP e segue o modelo de árvore de nós, onde cada nó representa um conjunto de atributo com seus valores. O LDAP é uma alternativa ao DAP - Directory Access Protocol .
Um Serviço de Diretório é um serviço de rede que identifica todos os recursos disponíveis em uma rede e mantém informações sobre estes dispositivos (contas de usuários, grupos, computadores, recursos, políticas de segurança etc.) em um banco de dados tornando estes recursos disponíveis para usuários e aplicações.
Um diretório é um banco de dados com informações sobre usuários, senhas, recursos e outros elementos necessários ao funcionamento de um sistema.
Um domínio pode ser visto como um conjunto de servidores, estações de trabalho, bem como as informações do diretório. Todos os servidores que contém uma cópia da base de dados do Active Directory fazem parte do domínio.
Desta forma, se o seu servidor Web é um membro de um domínio de um Active Directory você pode obter e até atualizar suas informações no Active Directory via código.
A plataforma .NET possui um diversas classes no namespace System.DirecotryServices (Active Directory Services Interfaces - ADSI) que fornecem acesso aos diretórios usando um dos seguintes protocolos:
Veremos a seguir alguns exemplos de como acessar o AD e em para que tudo funcione corretamente a conta da ASP.NET que estiver em execução deve possuir permissão para acessar o Active Directory. Se você estiver usando o Visual Studio ou o Visual Web Developer e testando as páginas usando o servidor web embutido provavelmente terá esse acesso habilitado, de outra forma tente efetuar o login na sua máquina com uma conta que possui permissão de administrador neste domínio.
Se você deseja acessar o AD a partir de uma aplicação rodando sob o IIS , você deverá desabilitar o acesso anônimo para a aplicação no Internet Services Manager, desta forma que os usuários tenham que fornecer credenciais do domínio quando forem acessar a aplicação. (Tome cuidado ao alterar a alocação da conta anônima IUSR ou ao alterar permissões ASP .NET para o AD. Se for efetuar restrições faça-as restringindo o mínimo necessário.)
As principais classes no namespace System.DirecotoryServices são :
O primeiro passo a ser dado para usar o ADSI é fazer uma conexão com o recurso que você deseja acessar (o nó específico da árvore). Para procurar por recursos de todo o domínio você deve se conectar ao topo do nó e assim obter uma referência a raiz do diretório, e, para fazer isso você precisa especificar o URI no formato LDAP correto.
Para acessar o Active Directory local usamos a sintaxe : "LDAP://domain/name" . Exemplo:
Dim recurso as new DirectoryEntry("LDAP://macoratti.net") Obs: A definição do protocolo deve estar em letras maiúsculas: LDAP.
Após inicializar o recurso desejado (o nó da árvore) você precisa especificar uma string de consulta na classe DirectorySearcher. (Você pode definir diversos valores de parâmetros deste objeto para refinar a sua pesquisa). Assim, se você quer obter informações sobre o usuário Macoratti pode definir na propriedade Filter uma string de consulta como (cn=Macoratti) desta forma:
Dim busca As
New DirectorySearcher(recurso) 
busca.Filter = "(cn=Macoratti)" 
Nota:
|  Ao definir 
    a propriedade Filter você deve seguir as seguintes regras: 
 | 
em seguida você deve iniciar a busca chamando os seguintes métodos da classe DirectorySearcher:
O retorno é do tipo SearchResultCollection.
Outra propriedade que vale a pena citar é a PropertiesToLoad que permite a você especificar os valores que você deseja retornar na sua busca. Se você não especificar nada a busca irá retornar todas as propriedades, e , este é o valor padrão. Então se você tiver interesse somente em alguns valores defina os valores que você deseja usando esta propriedade; você faz isso incluindo as propriedades a esta coleção antes de iniciar a busca. Exemplo:
searcher.PropertiesToLoad.Add("nome") irá incluir a propriedade nome a lista de propriedades para retornar na busca.
Com isso você evita que todos as propriedades sejam carregadas na memória.
Após isto você pode executar a busca da seguinte forma:
Dim resultados as
SearchResultCollection
resultados = busca.FindAll()
Após realizar a busca você pode iterar sobre cada entrada SearchResult na coleção SearchResultCollection.
A classe SearchResult possui a propriedade Properties que retorna um objeto ResultPropertyCollection que contém todas as propriedades que você especificou. Ex:
For Each resultado 
As SearchResult In resultados 
     Dim propColl As ResultPropertyCollection = resultado.Properties
Next 
Onde ResultPropertyCollection expõe a propriedade PropertyNames que retorna uma coleção contendo nomes de todas as propriedades retornadas pela busca. Assim você pode percorrer esta coleção para obter os nomes. Ex:
For Each strKey As 
String In propColl.PropertyNames 
        For Each obProp As Object In propColl(strKey)
             Me.AppendPropertyNode(obTopNode, 
strKey, obProp) 
        Next 
Next
Finalizando você pode usar a propriedade PropertyNames para extrair valores específicos do coleção ResultPropertyCollection.
Vejamos a seguir algumas tarefas usando o Active Directory
Você pode criar os exemplos abaixo no Visual Basic 2005 Express ou Visual Studio 2005.
Crie um novo projeto do tipo Windows Application e utilize os seguintes namespaces:
Imports
system.textInclua no formulário o controle ListBox e o controle Button.
Obs: Se for necessário inclua uma referência a System.DirectoryServices clicando com o botão direito do mouse sobre o nome do projeto e selecione a opção Add Reference, em seguida na janela Add Reference , na aba .NET selecione System.DirectoryServices e clique em OK.
1- Listar os domínios de redes
| PrivateSub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim root As System.DirectoryServices.DirectoryEntry root = New System.DirectoryServices.DirectoryEntry("WinNT:") 
     
     ListBox1.Items.Add(dominio.Name) NextEnd Sub | 
Acima estou apontando para o provedor ADSI WinNT: que traz os domínios da rede.
2- Listar os computadores na rede
| Private Sub 
    Button4_Click(ByVal sender
    As System.Object, ByVal 
    e As System.EventArgs) 
    Handles Button4.Click Dim root As System.DirectoryServices.DirectoryEntry root = New System.DirectoryServices.DirectoryEntry("WinNT:") Dim dominio As System.DirectoryServices.DirectoryEntry 
 For Each dom In root.Children Dim computadores As System.DirectoryServices.DirectoryEntry computadores= New System.DirectoryServices.DirectoryEntry("WinNT://" + dominio.Name) 
     For Each comp In computers.Children If comp.SchemaClassName = "computador" Then ListBox1.Items.Add((comp.Name) End If Next Next End Sub | 
3- Obtendo uma lista de usuários do Active Directory
Vamos aplicar esta teoria toda em um exemplo básico: retornar uma lista de usuários encontrados no container "Users" do Active Directory no domínio local.
O código mostrado a seguir faz exatamente isso.
| Private Sub 
    Button1_Click(ByVal sender
    As System.Object, ByVal 
    e As System.EventArgs) 
    Handles Button1.Click 
     ' obtem uma reerencia ao Active Directory Atual' e exibe o nome do dominio Dim dominio As Domain = Domain.GetCurrentDomain() Dim nomeDominio As String = dominio.Name 
 
     
     Using searcher As New DirectorySearcher(root, "CN=Users") ' retorna a primeira ocorrência Dim result As SearchResult = searcher.FindOne() 
     builder.Append("No 'CN=Users' entry found.") Else ' obtem a entrada do diretorio para o caminho CN=Users Using entry As DirectoryEntry = result.GetDirectoryEntry() ' percorre todos as entradas filhas 
 Dim userEntry As String = child.Name ' remove "CN=" do nome retornado builder.Append(userEntry.Substring(userEntry.IndexOf("=") + 1) + "" & Chr(10) & "") Next End Using End If End Using End Using resultado = builder.ToString() ListBox1.Items.Add(resultado) End Sub | 
A seguir temos uma função para listar todos os usuários usando o Active Directory :
| Public Function ListarTodosUsuariosAD() As DataTable Dim LDAP As String = "<ValorDoWebConfig>"         Dim table As DataTable = New DataTable("Resultados")        table.Columns.Add("Nome")
        table.Columns.Add("Usuario")
        table.Columns.Add("Email")        Dim row As DataRow
        Dim deRoot As DirectoryEntry = New DirectoryEntry(LDAP)
        Dim deSrch As DirectorySearcher = New DirectorySearcher(deRoot, "(&(objectClass=user)(objectCategory=person))")        deSrch.PropertiesToLoad.Add("cn")
        deSrch.PropertiesToLoad.Add("userPrincipalName")
        deSrch.PropertiesToLoad.Add("sAMAccountName")
        deSrch.PropertiesToLoad.Add("mail")deSrch.Sort.PropertyName = "sAMAccountName"         Dim oRes As SearchResult
        For Each oRes In deSrch.FindAll()
            row = table.NewRow()
            row("Nome") = oRes.Properties("cn")(0).ToString()
            row("usuario") = oRes.Properties("sAMAccountName")(0).ToString()            If oRes.Properties.Contains("mail") Then
                row("Email") = oRes.Properties("mail")(0).ToString()
            End If
            table.Rows.Add(row)
        Next
        Return table
    End Function
 | 
4- Autenticação de usuários
Para autenticar usuários no AD crie um novo web site no VS ou no VWD 2005 e inclua uma classe ao seu projeto chamada Autoriza.vb; a seguir crie uma função chamada Autentica contendo o seguinte código:
| ImportsSystem.DirectoryServices PublicClass Autoriza Public Function Autentica(ByVal IpServer As String, ByVal User As String, ByVal Senha As String) As String Dim resutado As String = "" Try Dim oAD As DirectoryEntry = New DirectoryEntry("LDAP://" + IpServer, User, Senha) resutado = oAD.Name Catch ex As Exception Throw New Exception(ex.Message) End TryReturn resutado End Function End Class 
 | 
Agora na página Default.aspx inclua dois controle TextBox : txtUsuario e txtSenha e um botão de comando Button : btnLogin;
Agora no evento Click do botão de comando inclua o seguinte código:
| Protected
    Sub btnLogin_Click(ByVal 
    sender As Object,
    ByVal e As System.EventArgs)
    Handles btnLogin.Click Dim oAD As Autoriza = New Autoriza Try | 
Para um exemplo mais detalhado e robusto veja o link: http://www.microsoft.com/brasil/security/guidance/topics/devsec/secmod16.mspx
Na verdade o assunto sobre o Active Directory é muito amplo e o artigo pretende apenas mostrar o básico sobre este recurso mostrando algumas possibilidades de uso.
Nota: Em pesquisas que realizei na internet descobri que o Active Directory não é suportado pelo Windows XP.
Até o próximo artigo...
 
 
José Carlos Macoratti