Como: Usar a autenticação baseada em formulário com o Active Directory

Atualizado em: 26 de Maio de 2004
Nesta página
ObjetivosObjetivos
Aplica-se aAplica-se a
Como usar este móduloComo usar este módulo
ResumoResumo
Criar um aplicativo da Web com uma página de logonCriar um aplicativo da Web com uma página de logon
Configurar o aplicativo da Web para autenticação baseada em formulárioConfigurar o aplicativo da Web para autenticação baseada em formulário
Desenvolver o código de autenticação LDAP para consultar o usuário no Active DirectoryDesenvolver o código de autenticação LDAP para consultar o usuário no Active Directory
Desenvolver o código de recuperação de grupo LDAP para consultar a participação do grupo do usuárioDesenvolver o código de recuperação de grupo LDAP para consultar a participação do grupo do usuário
Autenticar o usuário e criar uma permissão de autenticação baseada em formulárioAutenticar o usuário e criar uma permissão de autenticação baseada em formulário
Implementar um manipulador de solicitações de autenticação para construir um objeto GenericPrincipalImplementar um manipulador de solicitações de autenticação para construir um objeto GenericPrincipal
Testar o aplicativoTestar o aplicativo

Objetivos

Use este módulo para:

Criar um aplicativo da Web que use a autenticação baseada em formulário para autenticar usuários no Active Directory.

Obter do Active Directory uma lista de grupos e listas de distribuição às quais um usuário autenticado pertence

Criar um objeto GenericPrincipal que esteja associado à solicitação do usuário da Web usando a propriedade HttpContext.Current.User.

Início da páginaInício da página

Aplica-se a

Este módulo aplica-se aos seguintes produtos e tecnologias:

Microsoft Windows XP ou Windows 2000 Server (com Service Pack 3) e sistemas operacionais posteriores

Active Directory

Microsoft .NET Framework versão 1.0 (com Service Pack 2) e versões posteriores

Microsoft Visual Studio 1.0 .NET e versões posteriores

Microsoft Visual C# .NET

Microsoft SQL Server– 2000 (com Service Pack 2) e versões posteriores

Início da páginaInício da página

Como usar este módulo

Para obter o máximo deste módulo:

Você deve ter experiência no uso do Visual C# .NET e do Visual Studio .NET.

Você deve ter experiência no desenvolvimento de aplicativos da Web usando ASP.NET.

Você deve ter experiência no uso do Active Directory.

É necessário ter acesso a uma instância do Active Directory que possa ser usada para testar o aplicativo – e que não seja um sistema de produção.

Leia o módulo 3 deste guia, "Autenticação e autorização". Ele fornece detalhes sobre vários mecanismos de autenticação e discute a segurança baseada em função .NET.

Leia o módulo 8 deste guia, "Segurança do ASP.NET". Ele fornece detalhes sobre a autenticação baseada em formulário da Web ASP.NET.

Início da páginaInício da página

Resumo

A autenticação baseada em formulário do ASP.NET permite que usuários se identifiquem digitando credenciais (um nome de usuário e uma senha) em um formulário da Web. Ao receber essas credenciais, o aplicativo da Web pode autenticar o usuário verificando as credenciais em uma origem de dados.

Este módulo descreve como autenticar usuários no serviço de diretório do Microsoft Active Directory usando o protocolo LDAP. Ele também descreve como recuperar uma lista de grupos de segurança e listas de distribuição às quais o usuário pertença e como configurar um objeto GenericPrincipal para uso com a autorização baseada em função do .NET.

Início da páginaInício da página

Criar um aplicativo da Web com uma página de logon

Este procedimento cria um aplicativo Visual C# simples da Web contendo uma página de logon, que permite a um usuário digitar um nome de usuário, uma senha e uma página padrão, que exibe o nome da identidade e informações sobre participação em um grupo associadas à solicitação da Web atual.

Para criar um aplicativo da Web com uma página de logon

1.

Inicie o Visual Studio .NET e crie um novo aplicativo Visual C# ASP.NET da Web denominado FormsAuthAD.

2.

Use o Solution Explorer para renomear o arquivo WebForm1.aspx como Logon.aspx.

3.

Adicione uma nova referência ao conjunto de módulos (assembly) no System.DirectoryServices.dll. Isso proporciona acesso ao espaço para nome System.DirectoryServices que contém tipos gerenciados para ajudar na consulta e manipulação do Active Directory.

4.

Adicione os controles listados na Tabela 1 a Logon.aspx para criar um formulário simples de logon.

Tabela 1: Controles de Logon.aspx

Tipo de controleTextoID

Rótulo

Nome do domínio:

-

Rótulo

Nome do usuário:

-

Rótulo

Senha

-

Caixa de texto

-

txtDomainName

Caixa de texto

-

txtUserName

Caixa de texto

-

txtPassword

Botão

Log On

btnLogon

Rótulo

 

lblError

5.

Defina a propriedade TextMode de txtPassword como Password.

6.

No Solution Explorer, clique com o botão direito do mouse em FormsAuthAd, aponte para Add e clique em Add Web Form.

7.

No campo Name, digite default.aspx e clique em Open.

8.

No Solution Explorer, clique com o botão direito do mouse em default.aspx e depois em Set As Start Page.

9.

Clique duas vezes sobre default.aspx para exibir o manipulador de eventos de carga de páginas.

10.

Adicione o código a seguir ao manipulador de eventos para exibir o nome da identidade associado à solicitação da Web atual.

Response.Write( HttpContext.Current.User.Identity.Name ); 
Início da páginaInício da página

Configurar o aplicativo da Web para autenticação baseada em formulário

Este procedimento edita o arquivo Web.config do aplicativo a fim de configurá-lo para a autenticação baseada em formulário.

A fim de configurar o aplicativo da Web para a autenticação baseada em formulário

1.

Use o Solution Explorer para abrir o arquivo Web.config.

2.

Localize o elemento <authentication> e altere o atributo mode para Forms.

3.

Adicione o seguinte elemento <forms> como um filho do elemento authentication e defina os atributos loginUrl, name, timeout e path conforme demonstrado a seguir:

<authentication mode="Forms"> 
  <forms loginUrl="logon.aspx" name="adAuthCookie" timeout="60" path="/"> 
  </forms> 
</authentication> 

4.

Adicione o seguinte elemento <authorization> abaixo do elemento <authentication>. Isto permitirá que apenas usuários autenticados acessem o aplicativo. O atributo loginUrl do elemento <authentication>, definido anteriormente, redirecionará solicitações não autenticadas para a página logon.aspx.

<authorization>  
  <deny users="?" /> 
  <allow users="*" /> 
</authorization> 

5.

Salve o arquivo Web.config.

6.

Inicie o snap-in MMC (Console de Gerenciamento Microsoft) do IIS.

7.

Clique com o botão direito do mouse no diretório virtual do aplicativo. Em seguida, clique em Propriedades.

8.

Clique na guia Segurança da pasta e no botão Editar no grupo Controle de acesso anônimo e autenticação.

9.

Marque a caixa de seleção Acesso anônimo e desmarque a caixa de seleção Permitir que o IIS controle a senha.

10.

Como a conta anônima padrão IUSR_MACHINE não possui permissão para acessar o Active Directory, crie uma nova conta menos privilegiada e digite os detalhes da conta na caixa de diálogo Métodos de Autenticação.

11.

Clique em OK e clique em OK novamente para fechar a caixa de diálogo Propriedades.

12.

Retorne ao Visual Studio .NET e adicione um elemento <identity> abaixo do elemento <authorization> em Web.config. Defina o atributo de representação como true. Dessa forma, ASP.NET representará a conta anônima especificada anteriormente.

<identity impersonate="true" /> 

Como resultado dessa configuração, todos as solicitações feitas ao aplicativo serão executadas no contexto de segurança da conta anônima configurada. O usuário fornecerá as credenciais por meio do formulário da Web para fins de autenticação no Active Directory, mas a conta usada para acessar o Active Directory será a conta anônima configurada.

Início da páginaInício da página

Desenvolver o código de autenticação LDAP para consultar o usuário no Active Directory

Este procedimento adiciona uma nova classe de auxiliar ao aplicativo da Web para encapsular o código LDAP. A classe inicialmente oferecerá um método IsAuthenticated para validar um domínio, nome de usuário e senha em um objeto de usuário do Active Directory.

Para desenvolver o código de autenticação LDAP a fim de consultar o usuário no Active Directory

1.

Adicione um novo arquivo de classe C# denominado LdapAuthentication.cs.

2.

Adicione uma referência ao conjunto de módulos (assembly) de System.DirectoryServices.dll.

3.

Adicione as instruções using a seguir no início de LdapAuthentication.cs.

using System.Text; 
using System.Collections; 
using System.DirectoryServices; 

4.

Renomeie o espaço para nome existente como FormsAuthAD.

5.

Adicione duas seqüências privadas à classe LdapAuthentication; uma para manter o caminho LDAP para o Active Directory e a outra para manter um atributo filter usado para pesquisar no Active Directory.

private string _path; 
private string _filterAttribute; 

6.

Adicione um construtor público que possa ser usado para inicializar o caminho do Active Directory.

public LdapAuthentication(string path) 
{ 
  _path = path; 
} 

7.

Adicione o método IsAuthenticated a seguir, que aceita um nome de domínio, um nome de usuário e uma senha, como parâmetros e retorna bool para indicar se existe ou não o usuário com a senha correspondente no Active Directory. O método inicialmente tenta estabelecer uma ligação com o Active Directory usando as credenciais fornecidas. Se esse procedimento for bem-sucedido, o método usará a classe gerenciada DirectorySearcher para pesquisar o objeto do usuário especificado. Se o membro _path for localizado, ele será atualizado para apontar para o objeto de usuário. O membro _filterAttribute será atualizado com o atributo de nome comum do objeto de usuário.

public bool IsAuthenticated(string domain, string username, string pwd) 
{ 
  string domainAndUsername = domain + @"\" + username; 
  DirectoryEntry entry = new DirectoryEntry( _path,  
                                             domainAndUsername, pwd); 
  try 
  {  
    // Bind to the native AdsObject to force authentication.  
    Object obj = entry.NativeObject; 
    DirectorySearcher search = new DirectorySearcher(entry); 
    search.Filter = "(SAMAccountName=" + username + ")"; 
    search.PropertiesToLoad.Add("cn"); 
    SearchResult result = search.FindOne(); 
    if(null == result) 
    { 
      return false; 
    } 
    // Update the new path to the user in the directory 
    _path = result.Path; 
    _filterAttribute = (String)result.Properties["cn"][0]; 
  } 
  catch (Exception ex) 
  { 
    throw new Exception("Error authenticating user. " + ex.Message); 
  } 
  return true; 
} 
Início da páginaInício da página

Desenvolver o código de recuperação de grupo LDAP para consultar a participação do grupo do usuário

Este procedimento estende a classe LdapAuthentication para proporcionar um método GetGroups que recuperará a lista de grupos da qual o usuário atual é membro. O método GetGroups retornará a lista de grupos como uma seqüência separada de pipes, conforme demonstrado a seguir.

"Group1|Group2|Group3|" 

Para desenvolver o código de recuperação de grupo do LDAP a fim de consultar a participação do grupo do usuário

1.

Adicione a implementação a seguir do método GetGroups à classe LdapAuthentication.

public string GetGroups() 
{ 
  DirectorySearcher search = new DirectorySearcher(_path); 
  search.Filter = "(cn=" + _filterAttribute + ")"; 
  search.PropertiesToLoad.Add("memberOf"); 
  StringBuilder groupNames = new StringBuilder(); 
  try 
  { 
    SearchResult result = search.FindOne(); 
    int propertyCount = result.Properties["memberOf"].Count; 
    String dn; 
    int equalsIndex, commaIndex; 
    for( int propertyCounter = 0; propertyCounter < propertyCount; 
         propertyCounter++) 
    { 
      dn = (String)result.Properties["memberOf"][propertyCounter]; 
      equalsIndex = dn.IndexOf("=", 1); 
      commaIndex = dn.IndexOf(",", 1); 
      if (-1 == equalsIndex) 
      { 
        return null; 
      } 
      groupNames.Append(dn.Substring((equalsIndex + 1),  
                        (commaIndex - equalsIndex) - 1)); 
      groupNames.Append("|"); 
    } 
  } 
  catch(Exception ex) 
  { 
    throw new Exception("Error obtaining group names. " + ex.Message); 
  }  
  return groupNames.ToString(); 
} 
Início da páginaInício da página

Autenticar o usuário e criar uma permissão de autenticação baseada em formulário

Este procedimento implementa o manipulador de eventos btnLogon_Click para autenticar usuários. Para usuários autenticados, você criará uma permissão baseada em formulário que contém a lista de grupos do usuário. Você então redirecionará o usuário para a página original solicitada (antes de redirecioná-lo para a página de logon).

Para autenticar o usuário e criar uma permissão de autenticação baseada em formulário

1.

Retorne ao formulário Logon.aspx e clique duas vezes sobre o botão Log On para criar um manipulador de eventos btnLogon_Click vazio.

2.

No início do arquivo, adicione a instrução using a seguir abaixo das instruções using existentes. Esse procedimento permite o acesso aos métodos FormsAuthentication.

using System.Web.Security; 

3.

Adicione o código para criar uma nova instância da classe LdapAuthentication inicializada para apontar para o Active Directory do LDAP, conforme demonstrado no código a seguir. Lembre-se de alterar o caminho para apontar para o servidor Active Directory.

// Path to you LDAP directory server. 
// Contact your network administrator to obtain a valid path. 
string adPath = "LDAP://yourCompanyName.com/DC=yourCompanyName,DC=com";  
LdapAuthentication adAuth = new LdapAuthentication(adPath); 

4.

Adicione o código a seguir para executar estas etapas:

1.

Autentique o chamador no Active Directory.

2.

Recupere a lista de grupos da qual o usuário é membro.

3.

Crie uma FormsAuthenticationTicket contendo a lista de grupos.

4.

Criptografe a permissão.

5.

Crie um novo cookie contendo a permissão criptografada.

6.

Adicione o cookie à lista de cookies retornados ao navegador do usuário.

try 
{ 
  if(true == adAuth.IsAuthenticated(txtDomainName.Text,  
                                    txtUserName.Text,  
                                    txtPassword.Text)) 
  { 
    // Retrieve the user's groups 
    string groups = adAuth.GetGroups(); 
    // Create the authetication ticket 
    FormsAuthenticationTicket authTicket =  
        new FormsAuthenticationTicket(1,  // version 
                                      txtUserName.Text, 
                                      DateTime.Now,  
                                      DateTime.Now.AddMinutes(60), 
                                      false, groups); 
    // Now encrypt the ticket. 
    string encryptedTicket = FormsAuthentication.Encrypt(authTicket); 
    // Create a cookie and add the encrypted ticket to the  
    // cookie as data. 
    HttpCookie authCookie =  
                 new HttpCookie(FormsAuthentication.FormsCookieName, 
                                encryptedTicket); 
    // Add the cookie to the outgoing cookies collection.  
    Response.Cookies.Add(authCookie);  
    // Redirect the user to the originally requested page 
    Response.Redirect( 
              FormsAuthentication.GetRedirectUrl(txtUserName.Text,  
                                                 false)); 
  } 
  else 
  { 
    lblError.Text =  
         "Authentication failed, check username and password."; 
  } 
} 
catch(Exception ex) 
{ 
  lblError.Text = "Error authenticating. " + ex.Message; 
} 
Início da páginaInício da página

Implementar um manipulador de solicitações de autenticação para construir um objeto GenericPrincipal

Este procedimento implementa o manipulador de eventos Application_AuthenticateRequest no arquivo global.asax e cria um objeto GenericPrincipal para o usuário atualmente autenticado. Ele conterá a lista de grupos da qual o usuário é membro, recuperada do FormsAuthenticationTicket contido no cookie de autenticação. Finalmente, você associará o objeto GenericPrincipal ao objeto HttpContext atual, que é criado para todas as solicitações da Web.

Para implementar um manipulador de solicitações de autenticação para construir um objeto GenericPricipal

1.

Use o Solution Explorer para abrir o arquivo global.asax.cs.

2.

Adicione as instruções using a seguir ao início do arquivo.

using System.Web.Security; 
using System.Security.Principal; 

3.

Localize o manipulador de eventos Application_AuthenticateRequest e adicione o código a seguir para obter o cookie que contém a FormsAuthenticationTicket criptografada, a partir do conjunto de cookies passado com a solicitação.

// Extract the forms authentication cookie 
string cookieName = FormsAuthentication.FormsCookieName; 
HttpCookie authCookie = Context.Request.Cookies[cookieName]; 
if(null == authCookie) 
{ 
  // There is no authentication cookie. 
  return; 
}  

4.

Adicione o código a seguir para extrair e descriptografar a FormsAuthenticationTicket do cookie.

FormsAuthenticationTicket authTicket = null; 
try 
{ 
  authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
} 
catch(Exception ex) 
{ 
  // Log exception details (omitted for simplicity) 
  return; 
} 
if (null == authTicket) 
{ 
  // Cookie failed to decrypt. 
  return;  
}  

5.

Adicione o código a seguir para analisar a lista separada de pipes de nomes de grupos anexada à permissão quando o usuário foi originalmente autenticado.

// When the ticket was created, the UserData property was assigned a // pipe delimited string of group names. 
String[] groups = authTicket.UserData.Split(new char[]{'|'}); 

6.

Adicione o código a seguir para criar um objeto GenericIdentity com o nome do usuário obtido do nome da permissão e um objeto GenericPrincipal que contém essa identidade, junto com a lista de grupos do usuário.

// Create an Identity object 
GenericIdentity id = new GenericIdentity(authTicket.Name,  
                                         "LdapAuthentication"); 
// This principal will flow throughout the request. 
GenericPrincipal principal = new GenericPrincipal(id, groups); 
// Attach the new principal object to the current HttpContext object 
Context.User = principal; 
Início da páginaInício da página

Testar o aplicativo

Este procedimento usa o aplicativo da Web para solicitar a página default.aspx. Você será redirecionado à página de logon para autenticação. Após uma autenticação bem-sucedida, o navegador será redirecionado para a página default.aspx originalmente solicitada. Isso extrairá e exibirá a lista de grupos à qual o usuário autenticado pertence, a partir do objeto GenericPrincipal que foi associado à solicitação atual pelo processo de autenticação.

Para testar o aplicativo

1.

No menu Build, clique em Build Solution.

2.

No Solution Explorer, clique com o botão direito do mouse em default.aspx e depois clique em View in Browser.

3.

Digite um nome de domínio, um nome de usuário e uma senha válidos. Em seguida, clique em Log On.

4.

Se sua autenticação for bem-sucedida, você deverá ser redirecionado para default.aspx. O código nesta página deve exibir o nome do usuário autenticado.
Para ver a lista de grupos da qual o usuário autenticado é membro, adicione o código a seguir ao final do manipulador de eventos Application_AuthenticateRequest no arquivo global.aspx.cs.

Response.Write("Grupos: " + authTicket.UserData + "<br>"); 

Início da páginaInício da página