ASP.NET Core ofrece un robusto framework para la gestión de la autenticación. Es recomendable aprovechar estas funcionalidades integradas en lugar de implementar soluciones personalizadas.
Configuración de la Autenticación
La configuración se realiza principalmente en el archivo Startup.cs dentro del método ConfigureServices.
using Microsoft.AspNetCore.Authentication.Cookies;
using Uap.Areas.Admin.Service; // Asegúrate de que este namespace sea correcto
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration;
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(); // O AddMvc() si prefieres
// Registrar servicios
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddScoped<IAdminService, AdminServiceImpl>(); // Servicio de ejemplo
// Configurar autenticación basada en Cookies
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = "/Account/Login"; // Ruta a la página de inicio de sesión
options.LogoutPath = "/Account/Logout"; // Ruta para cerrar sesión
options.AccessDeniedPath = "/Shared/AccessDenied"; // Ruta para acceso denegado
options.ExpireTimeSpan = TimeSpan.FromMinutes(30); // Duración de la cookie de autenticación
options.SlidingExpiration = true; // Extiende la cookie si el usuario está activo
});
// Configurar políticas de cookies
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true; // Solicitar consentimiento del usuario para cookies no esenciales
options.MinimumSameSitePolicy = SameSiteMode.Lax; // Política SameSite
});
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
// Importante: Asegurarse de que UseAuthentication se ejecute antes de UseAuthorization
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
// Si usas áreas, como en el ejemplo original
endpoints.MapAreaControllerRoute(
name: "areas",
areaName: "Admin",
pattern: "Admin/{controller=Home}/{action=Index}/{id?}");
});
}
}
Implementación del Inicio de Sesión
En tu controlador, por ejemplo, un controlador de cuenta o de administración, puedes implementar la lógica de inicio de sesión.
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Uap.Areas.Admin.Models; // Asume que AdminModel está aquí
using Uap.Areas.Admin.Service; // Asume que IAdminService está aquí
[Route("[controller]")]
public class AccountController : Controller
{
private readonly IAdminService _adminService;
public AccountController(IAdminService adminService)
{
_adminService = adminService;
}
[HttpPost("login")]
[AllowAnonymous] // Permite acceso anónimo a esta acción
public async Task<IActionResult> Login([FromBody] LoginViewModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
// Aquí iría tu lógica para validar las credenciales del usuario
// Ejemplo: bool isValid = _adminService.AuthenticateUser(model.Username, model.Password);
// Supongamos que _adminService.AuthenticateUser devuelve un objeto User si es válido
var authenticatedUser = _adminService.AuthenticateUser(model.Username, model.Password); // Método de ejemplo
if (authenticatedUser == null)
{
return Unauthorized("Credenciales inválidas.");
}
// Crear las claims del usuario
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, authenticatedUser.Username),
new Claim(ClaimTypes.Role, authenticatedUser.Role), // Por ejemplo, "Admin" o "User"
// Puedes añadir más claims según necesites
};
// Crear la identidad del usuario
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
// Crear el principal de seguridad
var principal = new ClaimsPrincipal(identity);
// Iniciar sesión al usuario
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties
{
IsPersistent = model.RememberMe // Opción para recordar al usuario
});
// Redireccionar al usuario a la página de origen o a una página por defecto
var returnUrl = Request.Form["returnUrl"]; // Si se pasa como parámetro en el form
if (string.IsNullOrEmpty(returnUrl) || !Url.IsLocalUrl(returnUrl))
{
returnUrl = Url.Content("~/"); // Página principal por defecto
}
// Podrías devolver Ok() si el cliente maneja la redirección, o redirigir aquí
// return LocalRedirect(returnUrl);
return Ok(new { Message = "Login successful", ReturnUrl = returnUrl });
}
[HttpPost("logout")]
[Authorize] // Requiere autenticación para cerrar sesión
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Login", "Account"); // Redirigir a la página de login tras cerrar sesión
}
}
// ViewModel de ejemplo para el login
public class LoginViewModel
{
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
// Modelo de usuario de ejemplo
public class User
{
public string Username { get; set; }
public string Role { get; set; }
// Otros datos del usuario
}
Protección de Rutas con Atributos
[Authorize]: Aplica este atributo a nivel de controlador o acción para restringir el acceso solo a usuarios autenticados. Si un usuario no autenticado intenta acceder a un recurso protegido, será redirigido a la ruta especificada enoptions.LoginPath.[AllowAnonymous]: Permite el acceso anónimo a una acción específica, incluso si el atributo[Authorize]está aplicado a nivel de controlador. Esto es útil para páginas de inicio de sesión, registro, etc.
Flujo de Autenticación
Tras un inicio de sesión exitoso, el servidor emite una cookie de autenticación cifrada. En las solicitudes posteriores, el navegador incluirá esta cookie, permitiendo al servidor identificar al usuario autenticado sin necesidad de que vuelva a ingresar sus credenciales. Si se intenta acceder a un recurso protegido por [Authorize] y el usuario no está autenticado, el flujo de autenticación lo redirigirá automáticamente a la página de inicio de sesión definida, usualmente incluyendo un parámetro returnUrl para redirigir de vuelta a la página solicitada originalmente tras el éxito del login.