Como criar um sistema Sistema de Autenticação em ASP .NET e C#

Veja neste artigo como criar um sistema de autenticação com login e senha de modo facilitado e básico utilizando as tecnologias ASP.NET e C#.

Para que estejam ligadas as informações entre a aplicação e as informações salvas, será criado dentro do SGBD Microsoft SQL Server Management Studio um novo banco de dados, com o nome de ExemploLogin.

Neste banco de dados será criada uma tabela com o nome de Usuario, que vai conter os campos código, login e senha para uma futura autenticação do sistema. Veja o conjunto de instruções descrito na Listagem 1 para o SGBD e executar.

SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Usuario]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Usuario]( [fun_codigo] [int] IDENTITY(1,1) NOT NULL, [fun_login] [nvarchar](50) NULL, [fun_senha] [nvarchar](50) NULL, CONSTRAINT [PK_Usuario] PRIMARY KEY CLUSTERED ( [fun_codigo] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END
Listagem 1. Estrutura para a criação da tabela Usuario com seus respectivos campos e tipos

Iniciando o Projeto

Agora iremos dar o início para o projeto, tendo o ambiente de desenvolvimento Microsoft Visual Studio 2010. Com ele aberto, vá ao menu superior FileNewProject e depois selecione a opção do projeto Windows Forms Control Library. Atribua o nome da nova biblioteca de ProjetoServiceDesk e selecione o local onde a aplicação será salva. Depois é só clicar em OK.

É preciso agora criar três pastas: uma com o nome de Controller para controlar as ações, outra com o nome de DAO para a comunicação com o banco de dados e, por fim, uma com o nome de Model para que sejam tratadas e modeladas as informações.

Dentro da pasta Controller será criado um arquivo de classe com o nome FuncionarioController.cs. Já na pasta DAO serão criados dois arquivos de classe com os nomes Banco.cs e FuncionarioBD.cs. Dentro da pasta Model será criado um arquivo de classe com o nome de Funcionario.cs.

Após, será criado um novo projeto (mesmo o projeto anterior estando aberto no Solution Explorer) e os passos serão os mesmos, só que ao invés de ser uma nova biblioteca, será um ASP.NET Web Application com o nome WebExemploLogin.

Por padrão, em algumas versões, o ambiente cria automaticamente algumas pastas e arquivos, então será necessário apagar alguns deles e deixar apenas as pastas Properties (Propriedades), References (Referências de bibliotecas) e Web.config.

Agora serão criados outros três arquivos: Default.aspx (que será a página inicial da aplicação web), Principal.aspx (onde será a página de acesso caso o usuário efetuou o login) e Logout.aspx para que o usuário saia da aplicação.

A estrutura do projeto e dos arquivos criados ficará de acordo com a Figura 1.

Figura 1. Hierarquia dos arquivos dentro dos dois projetos

Implementando o Projeto servicedesk

Dentro da classe Banco.cs [DAO] será implementado o código descrito na Listagem 2.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.SqlClient; using System.Data; namespace ProjetoServiceDesk.DAO { internal class Banco { private string _strConexao; private SqlCommand _comandoSQL; protected SqlCommand ComandoSQL { get { return _comandoSQL; } set { _comandoSQL = value; } } protected Banco() { _strConexao = @"Data Source=USUARIO-PC;Initial Catalog=ExemploLogin;Integrated Security=True;User Id="";Password="";"; _conn = new SqlConnection(_strConexao); _comandoSQL = new SqlCommand(); _comandoSQL.Connection = _conn; } protected Banco(string stringConexao) { _strConexao = stringConexao; _conn = new SqlConnection(_strConexao); _comandoSQL = new SqlCommand(); _comandoSQL.Connection = _conn; } protected bool AbreConexao(bool transacao) { try { _conn.Open(); if (transacao) { _transacao = _conn.BeginTransaction(); _comandoSQL.Transaction = _transacao; } return true; } catch { return false; } } protected bool FechaConexao() { try { if (_conn.State == ConnectionState.Open) _conn.Close(); return true; } catch { return false; } } protected void FinalizaTransacao(bool commit) { if (commit) _transacao.Commit(); else _transacao.Rollback(); FechaConexao(); } protected int ExecutaComando(bool transacao) { if (_comandoSQL.CommandText.Trim() == string.Empty) throw new Exception("Não há instrução SQL a ser executada."); int retorno; AbreConexao(transacao); try { retorno = _comandoSQL.ExecuteNonQuery(); } catch(Exception ex) { retorno = -1; throw new Exception("Erro ao executar o comando SQL:", ex); } finally { if (!transacao) FechaConexao(); } return retorno; } protected int ExecutaComando(bool transacao, out int ultimoCodigo) { if (_comandoSQL.CommandText.Trim() == string.Empty) throw new Exception("Não há instrução SQL a ser executada."); int retorno; ultimoCodigo = 0; AbreConexao(transacao); try { ultimoCodigo = Convert.ToInt32(_comandoSQL.ExecuteScalar()); retorno = 1; } catch(Exception ex) { retorno = -1; throw new Exception("Erro ao executar o comando SQL: ", ex); } finally { if (!transacao) FechaConexao(); } return retorno; } protected DataTable ExecutaSelect() { if (_comandoSQL.CommandText.Trim() == string.Empty) throw new Exception("Não há instrução SQL a ser executada."); AbreConexao(false); DataTable dt = new DataTable(); try { dt.Load(_comandoSQL.ExecuteReader()); } catch(Exception ex) { dt = null; throw new Exception("Erro ao executar o comando SQL: ", ex); } finally { FechaConexao(); } return dt; } protected double ExecutaScalar() { if (_comandoSQL.CommandText.Trim() == string.Empty) throw new Exception("Não há instrução SQL a ser executada."); AbreConexao(false); double retorno; try { retorno = Convert.ToDouble(_comandoSQL.ExecuteScalar()); } catch(Exception ex) { retorno = -1; throw new Exception("Erro ao executar o comando SQL: ", ex); } finally { FechaConexao(); } return retorno; } } }
Listagem 2. Classe Banco.cs responsável por efetuar transações, abrir conexão, fechar conexão e retornar dados do Banco de dados

Nessa classe existe o construtor Banco() que é responsável por conectar com o banco de dados através de uma string de conexão. Nela temos as funções AbreConexao (para abrir conexão com o banco de dados) e FechaConexao (para fechar a conexão). O método FinalizaTransacao() é responsável por finalizar alguma transação atual e o método ExecutaComando() é responsável por executar o comando SQL e retornar se houve ou não êxito na comunicação com o banco de dados. Já os métodos ExecutaSelect() e ExecutaScalar() são responsáveis por executares os comandos SQL retornando valores.

Observação: Dependendo de como foi instalado o SGBD Microsoft SQL Server, a string de conexão pode sofrer alterações.

Dentro da classe Funcionario.cs [Model] será implementado o código descrito na Listagem 3.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProjetoServiceDesk.Model { public class Funcionario { public Funcionario() { _codigo = 0; } #region Propriedades do Funcionario private int _codigo; public int Codigo { get { return _codigo; } set { _codigo = value; } } private string _login; public string Login { get { return _login; } set { _login = value; } } private string _senha; public string Senha { get { return _senha; } set { _senha = value; } } #endregion } }
Listagem 3. Classe Funcionario.cs responsável por receber o tipo de informação e enviar o mesmo para o banco de dados

São criadas propriedades para o código, login e senha, a fim de que os dados sejam tratados de acordo com o tipo de cada campo.

Agora dentro da classe FuncionarioBD.cs [Banco] será implementado o código descrito na Listagem 4.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProjetoServiceDesk.Model; using System.Data; namespace ProjetoServiceDesk.DAO { internal class FuncionarioBD : Banco { internal FuncionarioBD() { } internal Funcionario Autenticar(string login, string senha) { ComandoSQL.Parameters.Clear(); ComandoSQL.CommandText = @"select * from USUARIO where fun_login = @login and fun_senha = @senha"; ComandoSQL.Parameters.AddWithValue("@login", login); ComandoSQL.Parameters.AddWithValue("@senha", senha); DataTable dt = ExecutaSelect(); if (dt != null && dt.Rows.Count > 0) { Funcionario f = new Funcionario(); f.Codigo = Convert.ToInt32(dt.Rows[0]["fun_codigo"]); f.Login = dt.Rows[0]["fun_login"].ToString(); f.Senha = dt.Rows[0]["fun_senha"].ToString(); return f; } else return null; } } }
Listagem 4. Classe FuncionarioBD.cs responsável por executar a instrução de SQL e retornar dentro de um DataTable as informações retornadas

É criada uma função chamada Autenticar passando por parâmetros o login e senha, onde, através de comando SQL, verifica se ambos estão iguais. O DataTable retorna todas as informações como Código, Login e Senha e, se não tiver algo, retorna nulo.

Finalmente, dentro da classe FuncionarioController.cs [Controller] será implementado o código descrito na Listagem 5.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProjetoServiceDesk.Model; using ProjetoServiceDesk.DAO; namespace ProjetoServiceDesk.Controller { public class FuncionarioController { FuncionarioBD bd = new FuncionarioBD(); public Funcionario Autenticar(string login, string senha) { if (login != "" && senha.Trim().Length > 0) return new FuncionarioBD().Autenticar(login, senha); else return null; } public FuncionarioController() { } } }
Listagem 5. Classe FuncionarioController.cs controladora que é responsável por autenticar o usuário

É declarada uma instância referente à classe FuncionarioBD. Além disso, é criada uma função Autenticar, passando por parâmetros o login e a senha. Se o login for diferente de vazio e se a senha tiver tamanho maior que 0, então é executado o método Autenticar da classe FuncionarioBD, senão é retornado nulo.

Implementando a Aplicação Web

Partindo do princípio de que a ideia central desse artigo é criar um sistema de login, até agora meio caminho já foi andado, faltando agora implementar a parte visual e alguns detalhes que visam tornar operacional a aplicação.

Para adicionar aquele projeto que se refere a uma biblioteca DLL para esse projeto web, basta clicar com o botão direito em References, clicar em “Add Reference...” e localizar a pasta onde foi criado o arquivo DLL (geralmente localizado na aba Projects) e adicionar.

No arquivo Default.aspx, na parte [Source] adicione o código descrito na Listagem 6 para agilizar o processo.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebExemploLogin.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="Label1" runat="server" Text="Login: "></asp:Label> <asp:TextBox ID="txtLogin" runat="server"></asp:TextBox> <br /> <br /> <asp:Label ID="Label2" runat="server" Text="Senha: "></asp:Label> <asp:TextBox ID="txtSenha" runat="server"></asp:TextBox> <br /> <br /> <asp:Button ID="btnEntrar" runat="server" onclick="btnEntrar_Click" Text="Entrar" /> <br /> <br /> <asp:Label ID="lblMensagem" runat="server" Text="-"></asp:Label> <br /> <br /> </div> </form> </body> </html>
Listagem 6. Página Default.aspx onde está a parte visual e também é a página inicial do sistema

Nesta página existem duas caixas de texto: uma referente a entrada do login e outra para a entrada da senha. Além disso, existe um botão para que o usuário entre no sistema para autenticação e um label para que avise na tela se o usuário informou o login e/ou a senha inválida.

Agora, indo na parte [Design], basta apertar F7 ou clicar com o botão direito e ir para a opção View Code, para que os códigos descritos na Listagem 7 possam ser inseridos.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using ProjetoServiceDesk.Controller; using ProjetoServiceDesk.Model; namespace WebExemploLogin { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (Request.Cookies["Acesso"] != null && !IsPostBack) { txtLogin.Text = Request.Cookies["Acesso"]["funcionario"]; txtSenha.Attributes.Add("value", Request.Cookies["Acesso"]["senha"]); } if (Request.QueryString["msg"] != null) lblMensagem.Text = Request.QueryString["msg"]; txtLogin.Focus(); } protected void btnEntrar_Click(object sender, EventArgs e) { lblMensagem.Text = string.Empty; if (txtLogin.Text.Trim() != "") { Funcionario user = new FuncionarioController() .Autenticar(txtLogin.Text, txtSenha.Text); if (user != null) { Session["autenticado"] = "OK"; Session["codigoFuncionario"] = user.Codigo; Session["nomeFuncionario"] = user.Login; Session["senhaFuncionario"] = user.Senha; Server.Transfer("Principal.aspx"); } else lblMensagem.Text = "Usuário e/ou senha inválida."; } } } }
Listagem 7. Códigos referentes aos modos operacionais dos elementos HTML criados e é onde é responsável por realizar as ações dessa página Default.aspx

Dentro do Page_Load são criados dois cookies para que recebam as informações do login e da senha do usuário (funcionário). O label receberá uma mensagem caso haja algum erro na autenticação e o txtLogin receberá o foco.

No botão Entrar, o label recebe vazio, e se o login informado estiver diferente de vazio, é executado o método Autenticar da classe FuncionarioController(), passando por parâmetros o login e senha referentes a classe Funcionario do tipo user. Se o resultado for diferente de nulo, ou seja, se existir, então são criadas as sessões para armazenar os dados e depois é transferido para a página Principal.aspx; senão, aparece uma mensagem de erro.

No arquivo Principal.aspx, que será a página onde o usuário fez o login e com sucesso possa acessar a essa página, na parte [Source] será adicionado o código descrito na Listagem 8.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Principal.aspx.cs" Inherits="WebExemploLogin.Principal" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:Label ID="lblUsuario" runat="server" Text="-"></asp:Label> <br /> <br /> <asp:Button ID="btnSair" runat="server" onclick="btnSair_Click" Text="Sair" /> </div> </form> </body> </html>
Listagem 8. Códigos referentes ao layout da página: Principal.aspx onde são criados um label e um botão para sair do sistema

Agora, na parte do View Code dessa página será introduzida o código descrito na Listagem 9.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebExemploLogin { public partial class Principal : System.Web.UI.Page { public static void VerificaLogin() { if (HttpContext.Current.Session["autenticado"] == null || HttpContext.Current.Session["autenticado"].ToString() != "OK") { HttpContext.Current.Session.Abandon(); HttpContext.Current.Response.Redirect("Default.aspx?msg=Por favor, autentique-se"); } } protected void Page_Load(object sender, EventArgs e) { VerificaLogin(); if (Session["autenticado"] != null && Session["autenticado"] .ToString() == "OK") { lblUsuario.Text = string.Format("Código: <br/>Nome: <br/>Senha: ", Session["codigoFuncionario"].ToString(), Session["nomeFuncionario"].ToString(), Session["senhaFuncionario"].ToString()); } } protected void btnSair_Click(object sender, EventArgs e) { Response.Redirect("Logout.aspx"); } } }
Listagem 9. Códigos referentes a página Principal.aspx que se refere a busca de informações para serem mostradas na tela e ao botão de Sair

A função VerificaLogin() é responsável por identificar se houve a autenticação com êxito, e se for diferente de OK, então significa que não houve e a sessão é destruída, retornando uma mensagem para que o usuário autentique-se.

No Page_Load é chamada a função VerificaLogin() e o label criado anteriormente recebe o Código, o Login e a Senha do usuário autenticado.

No botão Sair que é responsável por sair do sistema encerrando a sessão, é chamado a página de Logout.aspx.

E finalmente dentro do View Code do arquivo Logout.aspx, será implementado os códigos descritos na Listagem 9.

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace ProjetoServiceDeskWeb { public partial class Logout : System.Web.UI.Page { public static void VerificaLogin() { if (HttpContext.Current.Session["autenticado"] == null || HttpContext.Current.Session["autenticado"].ToString() != "OK") { HttpContext.Current.Session.Abandon(); HttpContext.Current.Response .Redirect("Default.aspx?msg=Por favor, autentique-se"); } } protected void Page_Load(object sender, EventArgs e) { VerificaLogin(); if (Request.Cookies["Acesso"] != null) Response.Cookies["Acesso"].Expires = DateTime.Now.AddDays(-1); Session.RemoveAll(); Session.Abandon(); Response.Redirect("Default.aspx"); } } }
Listagem 9. Códigos responsáveis por buscar através da sessão em andamento os dados e também para encerrar a atual sessão, direcionando para a página Default.aspx

É desenvolvida a mesma função VerificaLogin() e chamada no Page_Load. Se o cookie criado anteriormente com o nome de Acesso for diferente de nulo, então ele é expirado, e a sessão é removida e é direcionado para a página Default.aspx.

Para finalizar o sistema, basta salvar todos os projetos e executar a aplicação com um Ctrl + F5 ou clicando com o botão direito em cima do arquivo Default.aspx e depois clicar em View in Browser.

Se executado no navegador for o Mozilla Firefox, vai aparecer o mesmo que na Figura 2.

Figura 2. Página Default.aspx sendo executada

Para fazer testes, basta adicionar algumas informações na tabela Usuario, no SQL Server, como login e senha. Retorne a aplicação e clique no botão Entrar.

Logo, se os dados emitidos forem incorretos, vai aparecer uma mensagem de usuário ou senha inválida, senão a página vai redirecionar para a Principal.aspx, onde vai conter todas as informações cadastradas e também um botão para Sair que encerrará a sessão e retornará para a página Default.aspx.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados