Como: Usar a autenticação baseada em formulário com o Active Directory
Atualizado em: 26 de Maio de 2004
Nesta página
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. |
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 |
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. |
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.
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 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 );
|
|
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. |
|
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;
}
|
|
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();
}
|
|
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;
}
|
|
|
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;
|
|
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>");
|
|