WebMatrix - Segurança e MemberShip - III


Na segunda parte deste artigo criamos a página de registro , fizemos a validação e usamos os recursos do helper WebSecurity para criar uma nova conta de usuário. Criamos também um helper para exibir informações desse processo.

Neste artigo vamos criar as páginas de login, log out e changepassword.

Vamos partir do site SegurancaMembros criado primeira parte do artigo e incrementado na segunda parte.

Abra então o site SegurancaMembros no WebMatrix clicando em My Sites e selecionando o site SegurancaMembros:

Criando a página de Login

Uma vez que o usuário já esteja registrado ele poderá realizar o login para acessar o site na próxima visita. Temos então que criar uma página de login que será acessada pelo link na página Default.cshtml que é gerado pelo helper ResumoConta para usuários não autenticados.

Vamos incluir um novo arquivo na raiz do site clicando no menu New -> New File, selecionando o template CSHTML e informando o nome Login.cshtml;

Nossa página de login também será a padrão : apresentará duas caixas de texto uma para informar o usuário e a outra para informar a senha e um checkbox com o texto: "Lembrar a senha neste computador".

Quando o formulário for enviado, vamos realizar algumas validações básicas para garantir que as informações são válidas.

Se a validação passar, vamos tentar logar o usuário usando o método WebSecurity.Login() e passando os parâmetros: username, password e lembrarMe;

Obs: o método de extensão AsBool() converte um valor string para um boleano.

Se o usuário tiver marcado a caixa de seleção lembrarMe, o método Login() irá definir o token de autenticação no cookie para ser mantido além da sessão atual.

Dessa forma, quando o usuário voltar ao site em uma data posterior, ele será automaticamente conectado como o token de autenticação no cookie se ele ainda for válido.

Se o método Login() método for bem sucedido, o usuário será redirecionado para a página inicial, caso contrário, uma formulário de erro será adicionado à ModelStateDictionary e uma mensagem de erro será mostrada pelo Helper ValidationSummary no topo da página.

Vamos alterar o código do arquivo Login.cshtml conforme abaixo:

@{
var username = "";
var password = "";
 if(IsPost)
 {
  username = Request["username"];
  password = Request["password"];
  var lembrarMe = Request["lembrarMe"].AsBool();
  // Validação
  if (username.IsEmpty()) {
    ModelState.AddError("username", "O usuário não pode estar vazio.");
  }
  if (password.IsEmpty()) {
    ModelState.AddError("password", "A senha deve ser informada.");
 }
 // tenta fazer o login
 if(ModelState.IsValid)
 {
    if(WebSecurity.Login(username, password, lembrarMe))
    {
       Response.Redirect("~/default");
    }
    else
    {
       ModelState.AddFormError("Não foi possível fazer o login.");
    }
 }
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Login</title>
<style>
.validation-summary-errors,span.field-validation-error { color: #FF0000; }
input.field-validation-error { border: 1px solid #FF0000;background-color: #FFCCCC; }
</style>
</head>
<body>
<h1>Login</h1>
@Html.ValidationSummary(true)
<form action="login" method="post">
  <div>
   @Html.Label("Usuario: ", "username")<br />
   @Html.TextBox("username", username)
   @Html.ValidationMessage("username")
  </div>
  <div>
   @Html.Label("Senha: ", "password")<br />
   @Html.Password("password")
   @Html.ValidationMessage("password")
 </div>
 <div>
   @Html.CheckBox("lembrarMe", new { value = "true" })
   @Html.Label("Lembrar a senha neste computador?", "lembrarMe")
 </div>
 <div>
 <input type="submit" value="Login" />
</div>
</form>
</body>
</html>

Executando o site teremos o resultado como previsto:

 
   

Se houver erros eles serão exibidos conforme figura abaixo:

Criando a página de logout

Vamos incluir um novo arquivo na raiz do site clicando no menu New -> New File e informando o nome Logout.cshtml;

A seguir defina o código abaixo neste arquivo:

O código apenas chama o método WebSecurity.Logout() e exibe o link para retornar para página Default.chstml.

A página Logout.chstml deverá ser exibida conforme abaixo:

Alterando a senha do usuário

A página para alterar a senha do usuário será acessada através do link do nome do usuário exibido pelo helper ResumoConta na página Default.chsmtl.

É uma característica de segurança essencial de qualquer site que os usuários sejam capazes de mudar a sua próprias senhas.

Para alterar a senha de uma conta, vamos usar o método WebSecurity.ChangePassword().

Este método requer três parâmetros: userName, CurrentPassword e newPassword e retorna um valor booleano que indica se a operação de mudança de senha foi bem sucedida.

Vamos criar um novo chamado ChangePassword.cshtml na pasta raiz do nosso site clicando no menu File->New File, selecionando o template CSHTML e informando o nome ChangePassword.cshtml;

A seguir vamos incluir neste arquivo o código a seguir:

@{
if (!WebSecurity.IsAuthenticated)
{
   Response.Redirect("default");
}
var currentPassword = "";
var newPassword1 = "";
var newPassword2 = "";
if(IsPost)
{
   currentPassword = Request["currentPassword"];
   newPassword1 = Request["newPassword1"];
   newPassword2 = Request["newPassword2"];
   // Validação
   if (currentPassword.IsEmpty()) {
     ModelState.AddError("currentPassword", "A senha atual deve ser informada.");
   }
   if (newPassword1.IsEmpty()) {
     ModelState.AddError("newPassword1", "Não pode ser vazia.");
   }
   if (newPassword2.IsEmpty()) {
     ModelState.AddError("newPassword2", "Não pode ser vazia.");
   }
   if(newPassword1 != newPassword2)
   {
     ModelState.AddError("newPassword1", "As senhas não conferem.");
   }
   // Tenta mudar a senha
   if(ModelState.IsValid)
   {
     var usuarioAtual = WebSecurity.CurrentUserName;
     if(WebSecurity.ChangePassword(usuarioAtual, currentPassword, newPassword1))
     {
        Response.Redirect("~/default");
     }
     else
     {
        ModelState.AddFormError("Não foi possível alterar a senha.");
     }
   }
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Alterar Senha</title>
<style>
.validation-summary-errors,span.field-validation-error { color: #FF0000; }
input.field-validation-error { border: 1px solid #FF0000;background-color: #FFCCCC; }
</style>
</head>
<body>
<h1>Alterar Senha</h1>
@Html.ValidationSummary(true)
<form action="changePassword" method="post">
  <div>
    @Html.Label("Senha Atual: ", "currentPassword")<br />
    @Html.Password("currentPassword")
    @Html.ValidationMessage("currentPassword")
  </div>
  <div>
    @Html.Label("Nova Senha: ", "newPassword1")<br />
    @Html.Password("newPassword1")
    @Html.ValidationMessage("newPassword1")
  </div>
  <div>
    @Html.Label("Confirme a Nova Senha: ", "newPassword2")<br />
   @Html.Password("newPassword2")
   @Html.ValidationMessage("newPassword2")
  </div>
<div>
<input type="submit" value="Alterar Senha" />
</div>
</form>
</body>
</html>

No código acima iniciamos verificando se o usuário esta autenticado (WebSecurity.IsAuthenticated). Caso o usuário não esteja logado ele será enviado para página padrão. Isto é necessário porque ele pode ter chegado à página através de outro link, mas não pode realmente ser autenticado no momento, então não faz sentido permitir a um usuário anônimo alterar senha, não é mesmo ?

Quando o formulário for enviado, realizamos algumas validações simples para garantir que todas as informações necessárias nos campos foram informadas e que os dois campos de senha têm valores correspondentes.

Em seguida, se os dados do formulário forem válidos, obtemos o nome do usuário atual, acessando a propriedade WebSecurity.CurrentUserName.

Finalmente, chamamos o método WebSecurity.ChangePassword(), passando os parâmetros necessários. Se a operação de mudança de senha for bem sucedido, o usuário é redirecionado para a página padrão.

Se a operação falhar, uma mensagem é adicionada ao ModelStateDictionary do formulário e o formulário é exibido novamente.

Assim concluímos a implementação das funcionalidades relacionadas com o login, registro , logout e alteração de senha de um usuário no nosso site.

Você pode incrementar o visual das páginas criando um estilo para elas e incluir outros ajustes para melhorar a interface com o usuário.

Pegue o projeto completo aqui: SegurancaMembros3.zip

Rom 8:12 Portanto, irmãos, somos devedores, não à carne para vivermos segundo a carne;

Rom 8:13 porque se viverdes segundo a carne, haveis de morrer; mas, se pelo Espírito mortificardes as obras do corpo, vivereis.

Rom 8:14 Pois todos os que são guiados pelo Espírito de Deus, esses são filhos de Deus.

Rom 8:15 Porque não recebestes o espírito de escravidão, para outra vez estardes com temor, mas recebestes o espírito de adoção, pelo qual clamamos: Aba, Pai!

Referências:


José Carlos Macoratti