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!
Opa… muito bom seu post.
Sou novato em ASP.NET e gostaria de pedir um help. No meu Global.aspx a linha HttpContext.Current.User = new GenericPrincipal(id, roles);
da erro:
Error 1 The type or namespace name ‘GenericPrincipal’ could not be found (are you missing a using directive or an assembly reference?)
Pode me ajudar?
Obrigado.
Ola Beto
Você tentou um using do System.Security.Principal ?
Opa,
Ótimo post.
Como associo os grupos criados no Sharepoint com as roles do web.config ? Como associo usuários à role Administrador?