Autenticación y autorización en ASP.NET CORE mediante cookies

Estrada Web Group
Estrada Web Group

Hay tantas formas de configurar la autenticación y autorización cunado desarrollamos una aplicación web. Core Identity es el método recomendado oficialmente para autenticar usuarios en ASP.NET Core. Como habrás adivinado, no somos fanáticos del enfoque recomendado para hacer que Core Identity "simplemente funcione".

Queremos usar tanto del framework  de authorization de ASP.NET como podamos mientras evitamos Core Identity. Afortunadamente, ASP.NET admite la autorización de cookies sin Core Identity y hay ejemplos de uso en el repositorio oficial.

En este artículo veremos un ejemplo sencillo de autorización y autenticación, si deseas puedes descargar el proyecto Sistema de Inventarios que estamos desarrollando y que puedes utilizar y tomar como base de autenticación y autorización.

Configurar la autenticación basada en cookies en ASP.NET Core

En primer lugar, se debe configurar el Servicio de autenticación para admitir la autorización basada en cookies. Esto se hace cuando se inicia la aplicación ASP.NET:

using System;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MyApp
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // Configure cookie based authentication
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                    .AddCookie(options =>
                    {
                        // Specify where to redirect un-authenticated users
                        options.LoginPath = "/login";

                        // Specify the name of the auth cookie.
                        // ASP.NET picks a dumb name by default.
                        options.Cookie.Name = "my_app_auth_cookie";
                    });

            // ...snip... Other ASP.NET Core configuration here!
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // Configure authentication.
            // This should be done before app.UseEndpoints() is called!
            app.UseAuthentication();
            app.UseAuthorization();

            // ...snip... Other ASP.NET Core configuration here!
        }
    }
}

Iniciar sesión como usuario en ASP.NET Core

Somos responsables de autenticar las credenciales del usuario. Si lo hacemos nosotros mismos, podemos admitir más fácilmente diferentes métodos de autorización sin preocuparnos de si Core Identity los admite:

using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Controllers
{
    [AllowAnonymous]
    public class LoginController : Controller
    {
        [HttpGet]
        [Route("/login")]
        public IActionResult GetLoginScreen()
        {
            return View("Login");
        }

        [HttpPost]
        [Route("/login")]
        public async Task<IActionResult> LoginUser(
            string username, string password, string returnUrl)
        {
            var loginValid = ValidateLogin(username, password);

            if (!loginValid)
            {
                TempData["LoginFailed"] = $"The username or password is incorrect.";

                return Redirect("/login");
            }
            else
            {
                await SignInUser(username);

                if (string.IsNullOrWhiteSpace(returnUrl) || !returnUrl.StartsWith("/"))
                {
                    returnUrl = "/";
                }

                return this.Redirect(returnUrl);
            }
        }

        private bool ValidateLogin(string username, string password)
        {
            // Check the user/pass here!
            // For example's sake, the credentials are always valid.
            return true;
        }

        private async Task SignInUser(string username)
        {
            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, username),
                new Claim("MyCustomClaim", "my claim value")
            };

            var claimsIdentity = new ClaimsIdentity(
                claims, CookieAuthenticationDefaults.AuthenticationScheme);

            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity));
        }
    }
}

Leer los claims de un usuario que ha iniciado sesión

Un usuario autenticado no es muy interesante si no podemos saber quién es. La Identidad del usuario contiene toda la información proporcionada cuando se inició sesión originalmente:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Controllers
{
    public class TestController : Controller
    {
        [HttpGet]
        [Route("/read-claims")]
        public IActionResult TestClaimReading()
        {
            var username = HttpContext.User.Identity.Name;
            var customClaim = HttpContext.User.FindFirst("MyCustomClaim");

            return Content($"User {username} has custom claim value: {customClaim.Value}");
        }
    }
}

Permitir solo usuarios autenticados en una página

No tiene mucho sentido tener usuarios autenticados si no podemos restringir el acceso a las páginas. Un atributo hace que esto sea rápido en ASP.NET:

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Controllers
{
    // The Authorize attribute can also be used on individual controller methods.
    [Authorize]
    public class BillingController : Controller
    {
        [HttpGet]
        [Route("/authorized-page")]
        public IActionResult TestAuthorizedPage()
        {
            return Content("Only an authorized user can see this page!");
        }
    }
}

Los ejemplos anteriores pueden parecer mucho código, ¡pero aun así es mejor que usar Core Identity! Con un poco de suerte, nunca tendremos que volver a mirar este código.

Compartir artículo:

Más artículos geniales

Kestrel el servidor web para ASP.NET Core

Kestrel el servidor web para ASP.NET Core

En este tutorial, veremos el servidor web Kestrel para ASP.NET Core. La forma en que alojamos nuestra aplicación en ASP.NET Core ha sufrido cambios drásticos con la versión anterior de ASP.NET

Ver artículo completo

Manténgase actualizado

Obtenga excelente contenido en su bandeja de entrada todas las semanas.
Solo contenido excelente, no compartimos su correo electrónico con terceros.
Subir al inicio de la pantalla