No artigo de hoje vamos criar uma aplicação ASP .NET Web Forms para acessar os dados de um banco de dados MySQL remotamente mostrando como podemos cifrar e decifrar senhas de usuários e também vamos implementar uma verificação de palavras proibidas impedindo que o usuário use termos não apropriados. |
Na figura abaixo vemos a nossa aplicação ASP .NET onde o usuário vai informar o nome do usuário e uma senha e ao submeter sua requisição a senha será cifrada e exibida em um controle GridView.
Note que estamos obtendo e exibindo o endereço IP do visitante e também estamos realizando uma verificação de palavras proibidas de forma a impedir que o usuário informe termos impróprios no nome do usuário e na senha. Este é um recurso muito usado em sites para evitar pessoas mal educadas.
Recursos usados
Objetivos
Aprendizado
Definindo o Banco de dados e a tabela no MySQL
Neste exemplo eu vou usar o meu banco de dados MySQL hospedado em meu servidor de hospedagem. Vou criar uma tabela chamada usuários usando a ferramenta phpMyAdmin.
Abaixo temos a estrutura da minha tabela Usuarios criada no phpMyAdmin:
Nota: Da mesma forma podemos usar o MySQL instalado na máquina local o que vai mudar são as permissões e a string de conexão.
Nossa tabela Usuarios possui 3 campos:
Id - chave primária do tipo auto increment
Usuario - varchar(50) - armazena o nome do usuário
Senha - varchar(200) - armazena a senha do usuário cifrada
Para realizar a conexão com meu banco de dados remoto eu preciso das seguintes informações:
HOST - nome do host o do endereço IP do servidor
USUARIO - nome do usuário com acesso ao banco de dados
SENHA - senha do usuário
BANCO - nome do banco de dados MySQL com permissão de acesso
A string de conexão que deverá ser montada tem a seguinte estrutura:
String stringConexao = "Database=" + BANCO + ";Data Source=" + HOST + ";User Id=" + USUARIO + ";Password=" + SENHA + "; pooling=false";
Com essas informações podemos criar o projeto ASP .NET no Visual Studio.
Criando a aplicação ASP .NET Web Forms
Abra o Visual Studio 2012 Express for web e clique em New Project;
A seguir selecione o template Visual C# -> Web -> ASP .NET Empty Web Application e informe o nome ASPNET_MySQL_CifraDecifra e clique em OK;
Agora vamos incluir um WebForm no projeto que será a nossa página principal.
No menu PROJECT clique em Add New Item e selecione o template Web Form informando o nome Default.aspx e clicando no botão Add;
Abra a página Default.aspx, selecione o modo Design e a partir da ToolBox inclua o seguintes controles:
Defina os controles na página conforme o leiaute abaixo:
Vamos configurar o nosso GridView definindo as colunas, o estilo do cabeçalho e das linhas e o evento OnRowDataBound() conforme o código a seguir:
<asp:GridView ID="gdvUsuarios" runat="server" AutoGenerateColumns="false" HeaderStyle-BackColor="#3AC0F2"
HeaderStyle-ForeColor="White" RowStyle-BackColor="#A2DEE2" OnRowDataBound = "OnRowDataBound" Width="411px">
<Columns>
<asp:BoundField DataField="Usuario" HeaderText="Usuário" />
<asp:BoundField DataField="Senha" HeaderText="Senha Cifrada" />
<asp:BoundField DataField="Senha" HeaderText="Senha Decifrada" />
</Columns>
<HeaderStyle BackColor="#3AC0F2" ForeColor="White"></HeaderStyle>
<RowStyle BackColor="#A2DEE2"></RowStyle>
</asp:GridView>
|
O método OnRowDataBound() gera o evento RowDataBound.
Antes do controle GridView poder ser processado, cada linha no controle deve ser vinculada à um registro na fonte de dados. O evento RowDataBound é disparado quando uma linha de dados (representada por um objeto GridViewRow) é vinculada aos dados no controle GridView. Isso permite que você forneça um método de manipulação de eventos, que executa uma rotina personalizada, tais como modificar os valores dos dados vinculados à linha, sempre que esse evento ocorrer.
Estamos usando esse evento para chamar uma rotina que decifra a senha exibida em uma linha do GridView.
Criando as classes para acesso a dados , criptografia e verificação de palavras proibidas
Embora a aplicação seja muito simples e eu poderia incluir todo o código na página Default.aspx mas como queremos estar aderentes às boas práticas vamos separar o código responsável pela conexão com banco de dados, pela cifragem e decifragem da senha e pela verificação das palavras proibidas em classes. Assim iremos criar 3 classes em nosso projeto:
Agindo assim teremos uma interface limpa e vamos facilitar a manutenção da nossa aplicação pois qualquer alteração em uma das funcionalidades deverá ser feita de forma mais simples. Assim, por exemplo, se houver alteração em uma funcionalidade de acesso a dados as outras partes da aplicação não serão afetadas.
Antes de prosseguirmos temos que incluir uma referência ao MySQL Connector/Net. Para isso você primeiro tem que fazer o download do componente na página - http://dev.mysql.com/downloads/connector/net/ - e descompactar na sua máquina.
A seguir no menu PROJECT clique em Add Reference e a seguir selecione a guia Browse e localize e marque o item MySql.Data.dll conforme mostrado abaixo:
1- Criando a classe Conexao.cs
No PROJECT clique em Add Class e a seguir informe o nome Conexao.cs. e digite o código abaixo neste arquivo:
using System;
using MySql.Data.MySqlClient;
using System.Data;
namespace ASPNET_MySQL_CifraDecifra
{
public class Conexao
{
public static string GetStringConexao()
{
try
{
//Informe aqui os dados de acesso ao banco [IMPORTANTE]
String HOST = "999.99.99.999";
String USUARIO = "seu usuario";
String SENHA = "sua senha";
String BANCO = "seu banco";
//Monta a string de conexão utilizando os dados informados anteriormente String stringConexao = "Database=" + BANCO + ";Data Source=" + HOST + ";User Id=" + USUARIO + ";Password=" + SENHA + "; pooling=false"; return stringConexao; } catch (Exception ex) { throw ex; } } public static MySqlConnection AbreConexao()
{
try
{
MySqlConnection con = new MySqlConnection(Conexao.GetStringConexao());
con.Open();
return con;
}
catch (Exception ex)
{
throw ex;
}
}
public static void FechaConexao(MySqlConnection cn)
{
try
{
cn.Close();
}
catch (Exception ex)
{
throw ex;
}
}
public static DataTable ExecutaComando(string comando, MySqlConnection con)
{
try
{
MySqlCommand cmd = new MySqlCommand(comando);
MySqlDataAdapter da = new MySqlDataAdapter();
DataTable dt = new DataTable();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
da.SelectCommand = cmd;
da.Fill(dt);
return dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
FechaConexao(con);
}
}
public static void ExecutaComando(string comando, MySqlConnection con, Usuario usuario)
{
try
{
MySqlCommand cmd = new MySqlCommand(comando);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@Usuario", usuario.Nome);
cmd.Parameters.AddWithValue("@Senha", Cripto.Cifra(usuario.Senha));
cmd.Connection = con;
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
finally
{
FechaConexao(con);
}
}
}
}
|
Na classe Conexao a utilização do namespace MySql.Data.MySqlClient e a definição dos métodos:
2- Criando a classe Cripto.cs
No PROJECT clique em Add Class e a seguir informe o nome Cripto.cs e digite o código abaixo neste arquivo:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace ASPNET_MySQL_CifraDecifra { public class Cripto { public static string Cifra(string textoPuro) { string chaveEncriptacao = "MAC2014SJRP"; byte[] bytesLimpos = Encoding.Unicode.GetBytes(textoPuro); using (Aes encryptor = Aes.Create()) { Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(chaveEncriptacao, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); encryptor.Key = pdb.GetBytes(32); encryptor.IV = pdb.GetBytes(16); using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(bytesLimpos, 0, bytesLimpos.Length); cs.Close(); } textoPuro = Convert.ToBase64String(ms.ToArray()); } } return textoPuro; } public static string Decifra(string textoCifrado)
{
string chaveEncriptacao = "MAC2014SJRP";
byte[] bytesCifrados = Convert.FromBase64String(textoCifrado);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(chaveEncriptacao, new byte[]
{ 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesCifrados, 0, bytesCifrados.Length);
cs.Close();
}
textoCifrado = Encoding.Unicode.GetString(ms.ToArray());
}
}
return textoCifrado;
}
}
}
|
Na classe Cripto usamos os recursos do namespace System.Security.Cryptography e definimos dois métodos:
Usamos a classe Rfc2898DeriveBytes que implementa a funcionalidade de derivação da chave baseada na senha, PBKDF2(Password-Based Key Derivation Function 2), passando gerador de número pseudo randômico baseado em HMACSHA1(Calcula um HMAC usando uma função hash SHA1)
A classe Rfc2898DeriveBytes usa uma senha, um salt e uma contagem de iteração e, em seguida, gera chaves por meio de chamadas para o método GetBytes.
3- Criando a classe Censura.cs
No PROJECT clique em Add Class e a seguir informe o nome Censura.cs e digite o código abaixo neste arquivo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
namespace ASPNET_MySQL_CifraDecifra
{
public class Censura
{
/// <summary>
/// carrega as palavras proibidas de um arquivo XML
/// em uma lista genérica (List(T)
/// </summary>
/// <param name="arquivo">O nome do arquivo que trata as palavras proibidas</param>
/// <returns></returns>
public static List<string> ListaPalavrasProibidas(string arquivo)
{
//cria uma nova lista para tratar as palavras proibidas
List<string> palavras = new List<string>();
//cria um novo XmlDocument, para ler o arquivo XML
XmlDocument xmlDoc = new XmlDocument();
//Usando SelectNodes vamos passar a consulta XPath
//de forma a poder navegar através dos nós XML do arquivo
string consulta = "/ListaPalavras/palavra";
//carrega documento XML
xmlDoc.Load(arquivo);
//percorre todos os XmlNodes e verifica o criterio XPath
foreach (XmlNode node in xmlDoc.SelectNodes(consulta))
{
//inclui um InnerText de cada ChildNodes encontrado
palavras.Add(node.ChildNodes[0].InnerText);
}
//retorna a lista preenchida List(T)
return palavras;
}
/// <summary>
/// Determina se uma palavra esta na lista de palavras proibidas
/// </summary>
/// <param name="palavra">a palavra a ser verificada</param>
/// <param name="arquivo">o nome do arquivo com as palavras proibidas</param>
/// <returns></returns>
public static bool IsPalavraProibida(string palavra,string arquivo)
{
//cria uma nova lista List(T) para tratar as palavras.
//Preenche a lista chamando o método ListaPalavrasProibidas
List<string> palavrasProibidas = Censura.ListaPalavrasProibidas(arquivo);
//percorre a lista
for (int i = 0; i < palavrasProibidas.Count; i++)
{
//em cada iteração comparamos a palavra com a lista
//se encontrar retorna true
if (palavra.ToLower() == palavrasProibidas[i].ToLower()) return true;
}
//se não encontrar retorna false
return false;
}
}
}
|
Na classe Censura vamos usar os recursos do Generics e do XML da plataforma .NET. Nesta classe definimos dois métodos:
Para criar o arquivo XML - ListaPalavrasProibidas.xml - podemos usar os recursos do Visual Studio.
Clique no menu PROJECT e a seguir em Add New Item;
A seguir clique em Visual C# -> XML File e informe o nome ListaPalavrasProibidas.xml e clique em Add;
Nosso arquivo XML terá a seguinte estrutura:
Observe que temos o nó Raiz - <ListaPalavras> e os nós filhos <palavra>. Usamos essa hierarquia para navegar no arquivo XML, carregar os dados do arquivo e realizar pesquisas também.
Para concluir a primeira parte deste artigo vamos criar uma classe Usuario com as propriedades Nome e Senha que representa um usuário do sistema.
No PROJECT clique em Add Class e a seguir informe o nome Usuario.cs e digite o código abaixo neste arquivo:
namespace ASPNET_MySQL_CifraDecifra
{
public class Usuario
{
public string Nome { get; set; }
public string Senha { get; set; }
}
}
|
Esta classe iremos usar para transferir os dados entre as classes e a camada de apresentação.
Em todas as classes os métodos foram definidos como estáticos (static) de forma a podermos chamá-los sem ter que criar uma instância das classes.
Na segunda parte do artigo iremos implementar as funcionalidades da aplicação ASP .NET usando os recursos criados.
Tito 3:10 Ao homem faccioso, depois da primeira e segunda admoestação, evita-o,
Tito 3:11 sabendo que esse tal está pervertido, e vive pecando, e já por si mesmo está condenado.
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#