Implementar autenticação baseada em formulários em um aplicativo ASP.NET usando C#.NET
Este artigo demonstra como implementar a autenticação baseada em formulários usando um banco de dados para armazenar os usuários. Ele se refere aos seguintes namespaces da Biblioteca de Classes do Microsoft .NET Framework:
System.Data.SqlClient
System.Web.Security
Versão original do produto: ASP.NET
Número original do KB: 301240
Requisitos
A lista a seguir descreve o hardware, o software, a infraestrutura de rede e os service packs recomendados de que você precisa:
- Visual Studio .NET
- Serviços de Informações da Internet (IIS) versão 5.0 ou posterior
- SQL Server
Criar um aplicativo ASP.NET usando o .NET em C#
- Abra o Visual Studio .NET.
- Crie um novo aplicativo Web ASP.NET e especifique o nome e o local.
Definir configurações de segurança no arquivo Web.config
Esta seção demonstra como adicionar e modificar as <authentication>
seções e <authorization>
de configuração para configurar o aplicativo ASP.NET para usar a autenticação baseada em formulários.
No Gerenciador de Soluções, abra o arquivo Web.config .
Altere o modo de autenticação para Formulários.
Insira a
<Forms>
tag e preencha os atributos apropriados. Copie o código a seguir e selecione Colar como HTML no menu Editar para colar o código na<authentication>
seção do arquivo:<authentication mode="Forms"> <forms name=".ASPXFORMSDEMO" loginUrl="logon.aspx" protection="All" path="/" timeout="30" /> </authentication>
Negue o acesso ao usuário anônimo na seção da
<authorization>
seguinte maneira:<authorization> <deny users ="?" /> <allow users = "*" /> </authorization>
Criar uma tabela de banco de dados de exemplo para armazenar detalhes dos usuários
Esta seção mostra como criar um banco de dados de exemplo para armazenar o nome de usuário, a senha e a função para os usuários. Você precisará da coluna de função se quiser armazenar funções de usuário no banco de dados e implementar a segurança baseada em função.
No menu Iniciar, selecione Executar e digite bloco de notas para abrir o Bloco de Notas.
Realce o código de script SQL a seguir, clique com o botão direito do mouse no código e selecione Copiar. No Bloco de Notas, selecione Colar no menu Editar para colar o seguinte código:
if exists (select * from sysobjects where id = object_id(N'[dbo].[Users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[Users] GO CREATE TABLE [dbo].[Users] ([uname] [varchar] (15) NOT NULL, [Pwd] [varchar] (25) NOT NULL, [userRole] [varchar] (25) NOT NULL, ) ON [PRIMARY] GO ALTER TABLE [dbo].[Users] WITH NOCHECK ADD CONSTRAINT [PK_Users] PRIMARY KEY NONCLUSTERED ([uname] ) ON [PRIMARY] GO INSERT INTO Users values('user1','user1','Manager') INSERT INTO Users values('user2','user2','Admin') INSERT INTO Users values('user3','user3','User') GO
Salve o arquivo como Users.sql.
No computador SQL Server, abra Users.sql no Analisador de Consultas. Na lista de bancos de dados, selecione pubs e execute o script. Essa operação cria uma tabela de usuários de exemplo e preenche a tabela no banco de dados do Pubs a ser usada com esse aplicativo de exemplo.
Criar uma página Logon.aspx
Adicione um novo formulário da Web ao projeto chamado Logon.aspx.
Abra a página Logon.aspx no editor e alterne para o modo HTML.
Copie o código a seguir e use a opção Colar como HTML no menu Editar para inserir o código entre as
<form>
tags:<h3> <font face="Verdana">Logon Page</font> </h3> <table> <tr> <td>Email:</td> <td><input id="txtUserName" type="text" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserName" Display="Static" ErrorMessage="*" runat="server" ID="vUserName" /></td> </tr> <tr> <td>Password:</td> <td><input id="txtUserPass" type="password" runat="server"></td> <td><ASP:RequiredFieldValidator ControlToValidate="txtUserPass" Display="Static" ErrorMessage="*" runat="server" ID="vUserPass" /> </td> </tr> <tr> <td>Persistent Cookie:</td> <td><ASP:CheckBox id="chkPersistCookie" runat="server" autopostback="false" /></td> <td></td> </tr> </table> <input type="submit" Value="Logon" runat="server" ID="cmdLogin"><p></p> <asp:Label id="lblMsg" ForeColor="red" Font-Name="Verdana" Font-Size="10" runat="server" />
Este formulário da Web é usado para apresentar um formulário de logon aos usuários para que eles possam fornecer seu nome de usuário e senha para fazer logon no aplicativo.
Para obter mais informações, consulte Classe RequiredFieldValidator.
Alterne para o modo Design e salve a página.
Codifique o manipulador de eventos para que ele valide as credenciais do usuário
Esta seção apresenta o código que é colocado na página code-behind (Logon.aspx.cs).
Clique duas vezes em Logon para abrir o arquivo Logon.aspx.cs .
Importe os namespaces necessários no arquivo code-behind:
using System.Data.SqlClient; using System.Web.Security;
Crie uma
ValidateUser
função para validar as credenciais do usuário examinando o banco de dados. Certifique-se de alterar aConnection
cadeia de caracteres para apontar para o banco de dados.private bool ValidateUser( string userName, string passWord ) { SqlConnection conn; SqlCommand cmd; string lookupPassword = null; // Check for invalid userName. // userName must not be null and must be between 1 and 15 characters. if ( ( null == userName ) || ( 0 == userName.Length ) || ( userName.Length > 15 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of userName failed." ); return false; } // Check for invalid passWord. // passWord must not be null and must be between 1 and 25 characters. if ( ( null == passWord ) || ( 0 == passWord.Length ) || ( passWord.Length > 25 )) { System.Diagnostics.Trace.WriteLine( "[ValidateUser] Input validation of passWord failed." ); return false; } try { // Consult with your SQL Server administrator for an appropriate connection // string to use to connect to your local SQL Server. conn = new SqlConnection( "server=localhost;Integrated Security=SSPI;database=pubs" ); conn.Open(); // Create SqlCommand to select pwd field from users table given supplied userName. cmd = new SqlCommand( "Select pwd from users where uname=@userName", conn ); cmd.Parameters.Add( "@userName", SqlDbType.VarChar, 25 ); cmd.Parameters["@userName"].Value = userName; // Execute command and fetch pwd field into lookupPassword string. lookupPassword = (string) cmd.ExecuteScalar(); // Cleanup command and connection objects. cmd.Dispose(); conn.Dispose(); } catch ( Exception ex ) { // Add error handling here for debugging. // This error message should not be sent back to the caller. System.Diagnostics.Trace.WriteLine( "[ValidateUser] Exception " + ex.Message ); } // If no password found, return false. if ( null == lookupPassword ) { // You could write failed login attempts here to event log for additional security. return false; } // Compare lookupPassword and input passWord, using a case-sensitive comparison. return ( 0 == string.Compare( lookupPassword, passWord, false )); }
Você pode usar um dos dois métodos para gerar o cookie de autenticação de formulários e redirecionar o usuário para uma página apropriada no
cmdLogin_ServerClick
evento. O código de exemplo é fornecido para ambos os cenários. Use qualquer um deles de acordo com sua necessidade.Chame o
RedirectFromLoginPage
método para gerar automaticamente o cookie de autenticação de formulários e redirecione o usuário para uma página apropriada nocmdLogin_ServerClick
caso:private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked); else Response.Redirect("logon.aspx", true); }
Gere o tíquete de autenticação, criptografe-o, crie um cookie, adicione-o à resposta e redirecione o usuário. Essa operação oferece mais controle sobre como você cria o cookie. Você também pode incluir dados personalizados junto com o
FormsAuthenticationTicket
neste caso.private void cmdLogin_ServerClick(object sender, System.EventArgs e) { if (ValidateUser(txtUserName.Value,txtUserPass.Value)) { FormsAuthenticationTicket tkt; string cookiestr; HttpCookie ck; tkt = new FormsAuthenticationTicket(1, txtUserName.Value, DateTime.Now, DateTime.Now.AddMinutes(30), chkPersistCookie.Checked, "your custom data"); cookiestr = FormsAuthentication.Encrypt(tkt); ck = new HttpCookie(FormsAuthentication.FormsCookieName, cookiestr); if (chkPersistCookie.Checked) ck.Expires=tkt.Expiration; ck.Path = FormsAuthentication.FormsCookiePath; Response.Cookies.Add(ck); string strRedirect; strRedirect = Request["ReturnUrl"]; if (strRedirect==null) strRedirect = "default.aspx"; Response.Redirect(strRedirect, true); } else Response.Redirect("logon.aspx", true); }
Certifique-se de que o seguinte código seja adicionado ao
InitializeComponent
método no código gerado pelo Web Form Designer:this.cmdLogin.ServerClick += new System.EventHandler(this.cmdLogin_ServerClick);
Criar uma página Default.aspx
Esta seção cria uma página de teste para a qual os usuários são redirecionados após a autenticação. Se os usuários navegarem até essa página sem primeiro fazer logon no aplicativo, eles serão redirecionados para a página de logon.
Renomeie a página WebForm1.aspx existente como Default.aspx e abra-a no editor.
Alterne para a visualização HTML e copie o seguinte código entre as
<form>
tags:<input type="submit" Value="SignOut" runat="server" id="cmdSignOut">
Esse botão é usado para fazer logoff da sessão de autenticação de formulários.
Alterne para o modo Design e salve a página.
Importe os namespaces necessários no arquivo code-behind:
using System.Web.Security;
Clique duas vezes em SignOut para abrir a página code-behind (Default.aspx.cs) e copie o seguinte código no
cmdSignOut_ServerClick
manipulador de eventos:private void cmdSignOut_ServerClick(object sender, System.EventArgs e) { FormsAuthentication.SignOut(); Response.Redirect("logon.aspx", true); }
Certifique-se de que o seguinte código seja adicionado ao
InitializeComponent
método no código gerado pelo Web Form Designer:this.cmdSignOut.ServerClick += new System.EventHandler(this.cmdSignOut_ServerClick);
Salve e compile o projeto. Agora você pode usar o aplicativo.
Observações adicionais
Talvez você queira armazenar senhas com segurança em um banco de dados. Você pode usar a
FormsAuthentication
função de utilitário de classe nomeadaHashPasswordForStoringInConfigFile
para criptografar as senhas antes de armazená-las no banco de dados ou no arquivo de configuração.Talvez você queira armazenar as informações de conexão SQL no arquivo de configuração (Web.config) para que possa modificá-las facilmente, se necessário.
Você pode considerar adicionar código para impedir que hackers que tentam usar diferentes combinações de senhas façam logon. Por exemplo, você pode incluir uma lógica que aceite apenas duas ou três tentativas de logon. Se os usuários não puderem fazer logon em algumas tentativas, talvez você queira definir um sinalizador no banco de dados para não permitir que eles façam logon até que os usuários reativem suas contas visitando uma página diferente ou ligando para sua linha de suporte. Além disso, você deve adicionar o tratamento de erros apropriado sempre que necessário.
Como o usuário é identificado com base no cookie de autenticação, talvez você queira usar o Secure Sockets Layer (SSL) neste aplicativo para que ninguém possa enganar o cookie de autenticação e qualquer outra informação valiosa que esteja sendo transmitida.
A autenticação baseada em formulários requer que seu cliente aceite ou habilite cookies em seu navegador.
O parâmetro timeout da seção de configuração controla
<authentication>
o intervalo no qual o cookie de autenticação é regenerado. Você pode escolher um valor que forneça melhor desempenho e segurança.Determinados proxies e caches intermediários na Internet podem armazenar em cache as respostas do servidor Web que contêm
Set-Cookie
cabeçalhos, que são retornados a um usuário diferente. Como a autenticação baseada em formulários usa um cookie para autenticar usuários, esse comportamento pode fazer com que os usuários acidentalmente (ou intencionalmente) se passem por outro usuário recebendo um cookie de um proxy intermediário ou cache que não foi originalmente destinado a eles.