Trabalhar com identidade e autenticação dentro do ASP.NET Core é um sistema de associação que permite que você adicionar a funcionalidade de logon ao seu aplicativo. Recentemente eu escrevi uma pequena aplicação já utilizando o Razor pages
Você pode configurar a identidade do ASP.NET Core para usar um banco de dados para armazenar os nomes de usuário, senhas e dados de perfil. Como alternativa, você pode usar seu próprio armazenamento persistente, no exemplo abaixo eu foquei principalmente na autenticação como um todo, e não fiz persistência a dados para deixarmos o artigo bem focado em autenticação.
Primeiramente, vamos criar um projeto do Asp.NET Core 2.0 com Razor Pages:


Após a criação do projeto, a estrutura de pastas da solução será a seguinte:

Note que eu criei duas pastas, Model e Service, onde eu criei as respectivas classes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AuthCookie.Model
{
public class User
{
public string Name { get; set; }
public string Email { get; set; }
public string Token { get; set; }
public string Password { get; set; }
public string PasswordHash { get; set; }
public DateTime CreateDate { get; set; }
}
}
using AuthCookie.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AuthCookie.Service
{
public interface IUserService
{
User Authenticate(string email, string password);
}
public class UserService : IUserService
{
public User Authenticate(string email, string password)
{
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password))
return null;
User user = new User { Email = email, Token = "Token", Name = "Usuário Codigo Simples" };
return user;
}
}
}
Com isto, dentro da minha página Index, eu criei um formulário simples, onde eu irei chamar o método de autenticação;
@page
@model IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
ViewData["Title"] = "Home page";
}
<br />
<p>
@Model.Message
</p>
<p>
Faça login:
</p>
<div asp-validation-summary="All"></div>
<form method="POST" class="form-group">
<div>Email: <input asp-for="Customer.Email" type="email" class="input-group" /></div>
<br />
<div>Password: <input asp-for="Customer.Password" type="password" class="input-group" /></div>
<br />
<input type="submit" class="btn btn-default" />
</form>
E agora o codebehind da minha página Index:
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using AuthCookie.Service;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace AuthCookie.Pages
{
public class IndexModel : PageModel
{
//instanciando uma classe de serviço por injeção
private IUserService _userService;
public string Message { get; private set; } = string.Empty;
public IndexModel(
IUserService userService
)
{
_userService = userService;
}
//fazendo bind da model para ser usada no front-end
[BindProperty]
public Model.User Customer { get; set; }
//metodo Get inicial
public void OnGet()
{
//verifica se o usuário está autenticado
if (User.Identity.IsAuthenticated)
{
Message += "Olá Usuário, você está autenticado";
}
else
{
Message += "Você não está autenticado";
}
}
//metodo post do formulario
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return RedirectToPage("/Index");
}
//faz a busca do usuário e verifica se existe
var user = _userService.Authenticate(Customer.Email, Customer.Password);
if (user == null)
return Unauthorized();
//declara claim de identidade
var claim = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.Token.ToString())
});
var claims = new[]
{
new Claim(ClaimTypes.Email, user.Email.ToString())
}.ToAsyncEnumerable().ToEnumerable();
//faz autenticação via Cookie
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity));
// redireciona para a Index novamente, porém já autenticado
return RedirectToPage("/Index");
}
}
}
Com isto vimos que foi necessário apenas dois métodos, o método Get que exibe uma mensagem na página informando se o usuário está logado ou não no sistema; e um método Post que captura as informações do formulário e realiza a autenticação do usuário de fato.
Além disto, precisamos configurar como o sistema irá se comportar com a autenticação, dentro da classe Startup.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AuthCookie.Service;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace AuthCookie
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddCors();
//adiciona a classe de serviço ao escopo para utilizarmos na página
services.AddScoped<IUserService, UserService>();
// configura autenticação por cookie
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(o => { o.LoginPath = new PathString("/index"); o.Cookie.Name = "codigosimples"; });
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
//adiciona autenticação ao projeto
app.UseAuthentication();
app.UseStaticFiles();
app.UseMvc();
}
}
}
E pronto! O sistema de autenticação deve funcionar agora sem maiores problemas. Lembrando que é um sistema simples e básico sem nenhuma validação ainda ou busca de usuário no banco, mas deve lhe ajudar e muito para criar um sistema básico de autenticação.
Todo o código está no meu github: https://github.com/jhomarolo/auth-aspnetcore
Espero que tenham gostado! Um grande abraço a todos!
