Este artigo passo a passo demonstra como um ASP.NET aplicação pode utilizar a autenticação de formulários para permitir aos utilizadores para autenticar no Active Directory utilizando o LIGHTWEIGHT Directory Access Protocol (). Depois do utilizador é autenticado e redireccionado, pode utilizar o método
Application_AuthenticateRequest do ficheiro global.asax para armazenar um objeto
GenericPrincipal na propriedade
HttpContext.User que flui durante o pedido.
Criar uma aplicação Web ASP.NET no Visual C# .NET
Siga estes passos para criar uma nova aplicação Web do ASP.NET com o nome FormsAuthAd no Visual C# .NET:
- Inicie o Microsoft Visual Studio NET..
- No menu ficheiro , aponte para Novo e, em seguida, clique em projecto .
- Clique em Visual C# Projects em Project Types e, em seguida, clique em ASP.NET Web Application em modelos .
- Na caixa localização , substitua WebApplication1 FormsAuthAd .
- Clique em OK .
- Clique com o botão direito do rato no nó de referências no Solution Explorer e, em seguida, clique em Add Reference .
- No separador .NET na caixa de diálogo Adicionar referência do , clique em System.DirectoryServices.dll , clique em Seleccionar e, em seguida, clique em OK .
Escrever o código de autenticação
Siga estes passos para criar um novo ficheiro de classe chamado LdapAuthentication.cs:
- No Solution Explorer, clique com o botão direito do rato no nó de projecto, aponte para Adicionar e, em seguida, clique em Adicionar novo item .
- Clique em classe em modelos .
- Escreva LdapAuthentication.cs na caixa Nome e, em seguida, clique em Abrir .
- Substitua o código existente no ficheiro LdapAuthentication.cs com o seguinte código.
using System;
using System.Text;
using System.Collections;
using System.DirectoryServices;
namespace FormsAuth
{
public class LdapAuthentication
{
private String _path;
private String _filterAttribute;
public LdapAuthentication(String path)
{
_path = path;
}
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;
}
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();
}
}
}
O código de autenticação aceita um domínio, um nome de utilizador, uma palavra-passe e um caminho para a árvore no Active Directory. Este código utiliza o fornecedor de directório LDAP.
O código na página logon.aspx chama o método
LdapAuthentication.IsAuthenticated e passa nas credenciais que são recolhidas do utilizador. Em seguida, é criado um objecto
DirectoryEntry com o caminho para a árvore de directórios, o nome de utilizador e a palavra-passe. O nome de utilizador deve estar no formato "domínio\utilizador". O objecto
DirectoryEntry tenta forçar o enlace
AdsObject obtendo a propriedade
NativeObject . Se tiver êxito, o atributo
CN para o utilizador é obtido por criar um objecto
DirectorySearcher e por filtragem
SAMAccountName . Depois do utilizador ser autenticado, o método
IsAuthenticated devolve
Verdadeiro .
Para obter uma lista de grupos que o utilizador pertence, este código chama o método de
LdapAuthentication.GetGroups . O método
LdapAuthentication.GetGroups obtém uma lista de grupos de segurança e de distribuição que o utilizador pertence por criar um objecto
DirectorySearcher e por filtragem de acordo com o atributo
memberOf . Este método devolve uma lista de grupos separados por encaminhamentos (pipes) (|).
Repare que o método
LdapAuthentication.GetGroups manipula e trunca cadeias. Isto reduz o comprimento de cadeia que é armazenada no cookie de autenticação. Se a cadeia não estiver truncada, o formato de cada grupo aparece da seguinte forma.
CN=...,...,DC=domain,DC=com
Isto pode criar uma cadeia muito longa. Se o comprimento desta cadeia é maior do que o comprimento do cookie, browsers podem não aceitar o cookie de autenticação e vai ser redireccionada para a página de início de sessão. No entanto, se estiver num ambiente de vários domínios, poderá ter de manter o nome de domínio do nome de grupo porque grupos nos domínios diferentes poderão ter o mesmo nome de grupo. Tem de manter o nome de domínio para um grupo a partir de outro.
A maioria dos browsers suportam cookies de 4096 bytes. Se esta cadeia pode potencialmente exceda o comprimento do cookie, poderá armazenar as informações de grupo no objecto de cache do ASP.NET ou numa base de dados. Em alternativa, poderá encriptar as informações de grupo e armazenar estas informações num campo de formulário ocultos.
Escrever o código de global.asax
O código no ficheiro global.asax fornece um processador de eventos
Application_AuthenticateRequest . Este processador de eventos obtém o cookie de autenticação da colecção
Context.Request.Cookies , desencripta o cookie e obtém a lista de grupos que será armazenado na propriedade
FormsAuthenticationTicket.UserData . Os grupos aparecem numa lista separada por pipe que é criada na página logon.aspx.
O código analisa a cadeia de uma matriz de cadeia para criar um objecto
GenericPrincipal . Depois do objecto
GenericPrincipal é criado, este objecto será colocado na propriedade
HttpContext.User .
- No Solution Explorer, clique com o botão direito do rato em global.asax e, em seguida, clique em Código .
- Adicione o seguinte código na parte superior do código - atrás Global.asax.cs ficheiro:
using System.Web.Security;
using System.Security.Principal;
- Substituir o processador de eventos vazia existente para Application_AuthenticateRequest o seguinte código.
void Application_AuthenticateRequest(Object sender, EventArgs e)
{
String cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie)
{//There is no authentication cookie.
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch(Exception ex)
{
//Write the exception to the Event Log.
return;
}
if(null == authTicket)
{//Cookie failed to decrypt.
return;
}
//When the ticket was created, the UserData property was assigned a
//pipe-delimited string of group names.
String[] groups = authTicket.UserData.Split(new char[]{'|'});
//Create an Identity.
GenericIdentity id = new GenericIdentity(authTicket.Name, "LdapAuthentication");
//This principal flows throughout the request.
GenericPrincipal principal = new GenericPrincipal(id, groups);
Context.User = principal;
}
Modificar o ficheiro Web.config
Nesta secção, configurar o
<forms>, o
<authentication> e o
<authorization> elementos no ficheiro Web.config. Com estas alterações, apenas utilizadores autenticados podem aceder à aplicação e os pedidos não autenticados são redireccionados para uma página logon.aspx. É possível modificar esta configuração para permitir que apenas determinados utilizadores e grupos de acesso à aplicação.
Substitua o código existente no ficheiro Web.config com o seguinte código.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authentication mode="Forms">
<forms loginUrl="logon.aspx" name="adAuthCookie" timeout="10" path="/" >
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<identity impersonate="true" />
</system.web>
</configuration>
Repare o
<identity impersonate="true" /> elemento de configuração. Isto faz com que o ASP.NET representar a conta que é configurada como a conta anónima da Microsoft (IIS). Como resultado nesta configuração, todos os pedidos para esta aplicação executado no contexto de segurança da conta configurada. O utilizador fornece credenciais para autenticação no Active Directory, mas a conta que aceda ao Active Directory é a conta configurada. Para mais informações, consulte as
References de secção.
Configurar o IIS para autenticação anónima
Para configurar o IIS para a autenticação anónima, siga estes passos:
- No IIS, expanda o nó de computador para o servidor, expanda Web Sites , expanda Web Site predefinido , clique com o botão direito do rato FormsAuthAd e, em seguida, clique em Propriedades .
- Clique no Separador ' segurança ' do e, em seguida, clique em Editar em controlo de acesso anónimo e autenticação .
- Certifique a conta anónima para a aplicação de uma conta que tenha permissão para o Active Directory.
- Clique para desmarcar a caixa de verificação Permitir que o IIS para controle a senha.
- Na secção ? autenticados acesso ?, desmarque a caixa de verificação ? A autenticação integrada do Windows ?.
- Clique em OK.
- Clique em Aplicar
A conta predefinida IUSR_
computername não tem permissão para o Active Directory.
Criar a página logon.aspx
Siga estes passos para criar um novo formulário da Web ASP.NET denominado logon.aspx:
- No Solution Explorer, clique com o botão direito do rato no nó de projecto, aponte para Adicionar e, em seguida, clique em Adicionar formulário de Web .
- Escreva logon.aspx na caixa Nome e, em seguida, clique em Abrir .
- No Solution Explorer, clique com o botão direito do rato logon.aspx e, em seguida, clique em Estruturador de vistas .
- Clique no separador HTML no Designer.
- Replace the existing code with the following code.
<%@ Page language="c#" AutoEventWireup="true" %>
<%@ Import Namespace="FormsAuth" %>
<html>
<body>
<form id="Login" method="post" runat="server">
<asp:Label ID="Label1" Runat=server >Domain:</asp:Label>
<asp:TextBox ID="txtDomain" Runat=server ></asp:TextBox><br>
<asp:Label ID="Label2" Runat=server >Username:</asp:Label>
<asp:TextBox ID=txtUsername Runat=server ></asp:TextBox><br>
<asp:Label ID="Label3" Runat=server >Password:</asp:Label>
<asp:TextBox ID="txtPassword" Runat=server TextMode=Password></asp:TextBox><br>
<asp:Button ID="btnLogin" Runat=server Text="Login" OnClick="Login_Click"></asp:Button><br>
<asp:Label ID="errorLabel" Runat=server ForeColor=#ff3300></asp:Label><br>
<asp:CheckBox ID=chkPersist Runat=server Text="Persist Cookie" />
</form>
</body>
</html>
<script runat=server>
void Login_Click(Object sender, EventArgs e)
{
String adPath = "LDAP://corp.com"; //Fully-qualified Domain Name
LdapAuthentication adAuth = new LdapAuthentication(adPath);
try
{
if(true == adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text))
{
String groups = adAuth.GetGroups();
//Create the ticket, and add the groups.
bool isCookiePersistent = chkPersist.Checked;
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(1, txtUsername.Text,
DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups);
//Encrypt the ticket.
String encryptedTicket = FormsAuthentication.Encrypt(authTicket);
//Create a cookie, and then add the encrypted ticket to the cookie as data.
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
if(true == isCookiePersistent)
authCookie.Expires = authTicket.Expiration;
//Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie);
//You can redirect now.
Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, false));
}
else
{
errorLabel.Text = "Authentication did not succeed. Check user name and password.";
}
}
catch(Exception ex)
{
errorLabel.Text = "Error authenticating. " + ex.Message;
}
}
</script> - Modifique o caminho na página logon.aspx para apontar para o servidor de directórios de LDAP.
A página logon.aspx é uma página que recolhe as informações dos métodos de chamada e de utilizador na classe
LdapAuthentication . Depois do código autentica o utilizador e obtém uma lista de grupos, o código cria um objecto
FormsAuthenticationTicket , encripta a permissão, adiciona a permissão encriptada a um cookie, adiciona o cookie ao conjunto
HttpResponse.Cookies e, em seguida, redirecciona o pedido para o URL que foi originalmente pedido.
Modificar a página WebForm1.aspx
Página WebForm1.aspx é a página é pedida originalmente. Quando o utilizador pede nesta página, o pedido é redireccionado para o logon.aspx página. Depois do pedido estiver autenticado, o pedido é redireccionado para a página WebForm1.aspx.
- No Solution Explorer, clique com o botão direito do rato em WebForm1.aspx e, em seguida, clique em View Designer .
- Clique no separador HTML no Designer.
- Substitua o código existente com o seguinte code.
<%@ Page language="c#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Security.Principal" %>
<html>
<body>
<form id="Form1" method="post" runat="server">
<asp:Label ID="lblName" Runat=server /><br>
<asp:Label ID="lblAuthType" Runat=server />
</form>
</body>
</html>
<script runat=server>
void Page_Load(Object sender, EventArgs e)
{
lblName.Text = "Hello " + Context.User.Identity.Name + ".";
lblAuthType.Text = "You were authenticated using " + Context.User.Identity.AuthenticationType + ".";
}
</script>
- Guarde todos os ficheiros e, em seguida, compilar o projecto.
- Pedir a página WebForm1.aspx. Repare que são redireccionados para logon.aspx.
- Escreva as credenciais de início de sessão e, em seguida, clique em Submeter . Quando são redireccionados para WebForm1.aspx, repare que aparece o nome de utilizador e LdapAuthentication consiste na autenticação tipo para a propriedade Context.User.AuthenticationType .
Nota A Microsoft recomenda que utilize (Secure Sockets Layer) encriptação quando utilizar a autenticação de formulários. Isto acontece porque o utilizador é identificado baseia o cookie de autenticação e encriptação SSL esta aplicação impede que qualquer pessoa comprometer o cookie de autenticação e quaisquer outras informações importantes que está a ser transmitidas.
Para obter mais informações, clique números de artigo que se seguem para visualizar os artigos na base de dados de conhecimento da Microsoft:
306590
(http://support.microsoft.com/kb/306590/
)
Descrição geral da segurança do ASP.NET
317012
(http://support.microsoft.com/kb/317012/
)
Identidade de processo e um pedido no ASP.NET
311495
(http://support.microsoft.com/kb/311495/
)
Como implementar segurança baseada em funções com a autenticação baseada em formulários na aplicação do ASP.NET utilizando o Visual C# .NET
313091
(http://support.microsoft.com/kb/313091/
)
A criação de chaves utilizando o Visual Basic .NET para utilização na autenticação de formulários
313116
(http://support.microsoft.com/kb/313116/
)
Pedidos de autenticação de formulários não são dirigidos para a página loginUrl