Ola Pessoal
Muita gente pergunta como criarmos um sistema de autenticação eficiente em ASP.NET, sem utilizar Profile e a estrutura de tabelas própria do ASP.NET. Pois bem vou mostrar aqui uma maneira bem simples de criar este sistema de forma personalizada utilizando também regras de acesso.
Bom para efetuar nossa exmplicação vamos partir de um exemplo real. Imaginando que criamos uma estrutura de tabelas em nosso banco capaz de armazenar as informações dos usuários, como dados básicos e perfis de acesso, esta estrutura pode ser modelada da maneira que preferir. Abaixo vou citar um exemplo:
Neste exemplo simples criamos uma tabela de usuários, uma tabela de perfil que irá armazenar as regras de acesso, e uma tabela UsuarioxPerfil que vamos relacionar as regras de acesso de cada usuário para o sistema.
Agora precisamos criar nossa código para autenticação. Primeiro criamos algumas procedures de consulta as informações, seguindo nosso exemplo criamos uma procedure exemplo para o retorno des dados do usuário:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Adriano Bertucci
-- Create date: 02 de janeiro de 2009
-- Description: Busca Informações para login no sistema
-- =============================================
ALTER PROCEDURE [dbo].[CPBB_Logar]
@Login as varchar(20),
@Senha as varchar(50)
AS
BEGIN
SET NOCOUNT ON;
--Retorna as Regras(Perfil) caso o usuário e senha sejam válidos
SELECT P.PerfilId,P.Nome FROM Usuario U
LEFT JOIN UsuarioxPerfil UP
ON U.UsuarioId = UP.UsuarioId
LEFT JOIN Perfil P
ON UP.PerfilId = P.PerfilId
WHERE U.Login = @Login and U.Senha = @Senha
END
Acima temos o código de uma simples procedure que ira retornar as regras de acesso do usuário de acordo com a validação de usuário e senha.
Agora vamos ao código .NET, com nosso projeto ASP.NET criado usaremos os métodos de autenticação do próprio ASP.NET. Como primeiro passo criei um componente de login que o qual colocarei o código de autenticação conforme descrito abaixo:
protected void btnLogar_Click(object sender, ImageClickEventArgs e)
{
//Busca os controles com o usuário e senha digitados pelo usuário
string Login = ((TextBox)LoginView.FindControl("txtLogin")).Text;
string Senha = ((TextBox)LoginView.FindControl("txtSenha")).Text;
//Executa a função logar a qual dispara a procedure e retorna
//o perfil de acesso
string Perfil = CPBB.Servico.Usuario.Logar(Login, Senha);
//Verifica o retorno do login
if (!String.IsNullOrEmpty(Perfil))
{
#region " === Autenticação === "
//Inicializamos o processo de autenticação
FormsAuthentication.Initialize();
//Criamos um ticket com os dados do usuário
//reparem que passamos inclusive os perfis carregados
//o ticket será a base da nossa autenticação
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Login, DateTime.Now,
DateTime.Now.AddMinutes(Convert.ToInt32(ConfigurationManager.AppSettings["CookieTimeOut"])),
false, Perfil, FormsAuthentication.FormsCookiePath);
//Criptografamos o ticket por questão se segurança
string hash = FormsAuthentication.Encrypt(ticket);
//Criamos um cookie(será usado para validação do asp.net)
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
//Setamos a persistencia do cookie
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
//Em fim adicionamos o cookie a nossa aplicação.
Response.Cookies.Add(cookie);
//Retornamos para a página que foi solicitada
string returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "/";
Response.Redirect(returnUrl);
#endregion
}
else
{
ScriptManager.RegisterStartupScript(Page, Page.GetType(), "Login", "alert('" +
Resources.MensagensAlertas.LoginInvalido + "');", true);
}
}
Apenas como demonstração segue abaixo a função de login a qual é utilizada para a consulta ao banco de dados em nosso exemplo representada por CPBB.Servico.Usuario.Logar(Login, Senha);
public static string Logar(string Login, string Senha)
{
string Perfil = string.Empty;
//Consultamos o banco de dados para validar o usuário
SubSonic.StoredProcedure SP = CPBB.DAL.SPs.CpbbLogar(Login, FormsAuthentication.HashPasswordForStoringInConfigFile(Senha,"sha1"));
System.Data.DataSet ds = SP.GetDataSet();
CPBB.DAL.PerfilCollection cperfil = new CPBB.DAL.PerfilCollection();
cperfil.Load(ds.Tables[0]);
//Carregamos o(s) perfil(s)
foreach (CPBB.DAL.Perfil perfil in cperfil)
{
Perfil += perfil.Nome + ",";
}
cperfil = null;
SP = null;
ds.Dispose();
return Perfil;
}
Bom pessoal, feito isso agora temos que configurar nosso Global.asax, ele será o responsável por carregar os perfis do usuário para que o ASP.NET o reconheça. Vamos ao código:
protected void Application_AuthenticateRequest(Object sender,EventArgs e)
{
//Verificamos a existencia de um usuário na aplicação
if (HttpContext.Current.User != null)
{
//Se o usuário esta autenticado( passou pelo login inicial )
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
//Usando as classes de Identidade do ASP.NET vamos pegar as regras
// e carregar para a aplicação
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id =(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
Repare que utilizamos o método Application_AuthenticateRequest do Global.asax, ele é usado sempre que um usuário se autentica na aplicação.
Feito isso agora basta usar as configurações no web.Config para setar o acesso as páginas, como por exemplo:
<location path="admin">
<system.web>
<authorization>
<allow roles="Administrador"/>
<deny users="*"/>
</authorization>
</system.web>
</location>
Bom pessoal tentei demonstrar de maneira rápida de fazer uma autenticação via asp.net usando roles, caso tenha alguma dúvida é só avisar!
Bom divertimento!