Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/interezante456-pixel/proyecto-dise-o/llms.txt

Use this file to discover all available pages before exploring further.

Tienda MiCholo utiliza ASP.NET Core Identity para gestionar por completo la autenticación y autorización de sus usuarios. El sistema emplea autenticación basada en cookies, dos roles predefinidos (Admin y Vendedor) y está completamente integrado con EF Core a través de AppDbContext. No existe ningún proveedor de identidad externo: todas las credenciales se almacenan en la base de datos DB_TIENDA_MICHOLO.

Flujo de autenticación

1

Acceso a una ruta protegida

Cuando un usuario no autenticado intenta visitar cualquier ruta decorada con [Authorize] (por ejemplo, /Producto/Listar), el middleware de autenticación detecta que no hay una cookie de sesión válida y redirige automáticamente a /Account/Login, la ruta configurada como LoginPath.
2

POST /Account/Login — validación de credenciales

El controlador recibe el LoginViewModel del formulario y llama a SignInManager.PasswordSignInAsync. Este método verifica el hash de la contraseña almacenado en AspNetUsers y, si es correcto, emite la cookie de autenticación.
Controllers/AccountController.cs
var result = await _signInManager.PasswordSignInAsync(
    model.Email,
    model.Password,
    model.RememberMe,
    lockoutOnFailure: false);
3

Inicio de sesión exitoso — redirección

Si result.Succeeded es true, la cookie de sesión queda establecida en el navegador y el usuario es redirigido a /Producto/Listar, la página principal de la aplicación.
Controllers/AccountController.cs
if (result.Succeeded)
{
    return RedirectToAction("Listar", "Producto");
}
4

Inicio de sesión fallido — mensaje de error

Si las credenciales son incorrectas, se agrega un error al ModelState y la vista de login se vuelve a renderizar con el mensaje de error visible para el usuario.
Controllers/AccountController.cs
ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido.");
5

POST /Account/Logout — cierre de sesión

Al hacer clic en “Cerrar sesión”, el navegador envía una petición POST a /Account/Logout. El controlador llama a SignInManager.SignOutAsync(), que invalida e elimina la cookie de autenticación. Tras esto, el usuario es redirigido a /Producto/Listar, que a su vez lo enviará de vuelta al login al no estar autenticado.
Controllers/AccountController.cs
[HttpPost]
public async Task<IActionResult> Logout()
{
    await _signInManager.SignOutAsync();
    return RedirectToAction("Listar", "Producto");
}

Configuración de cookies

Las rutas de redirección para autenticación y acceso denegado se configuran en Program.cs mediante ConfigureApplicationCookie:
Program.cs
builder.Services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = "/Account/Login";
    options.AccessDeniedPath = "/Account/AccessDenied";
});
OpciónValorEfecto
LoginPath/Account/LoginDestino de la redirección cuando se requiere autenticación
AccessDeniedPath/Account/AccessDeniedDestino cuando el usuario está autenticado pero carece del rol necesario

Identity con EF Core

AppDbContext extiende IdentityDbContext<IdentityUser>, lo que vincula el sistema de identidad directamente con la base de datos de la tienda. No se requiere una base de datos separada para los usuarios:
Data/AppDbContext.cs
public class AppDbContext : IdentityDbContext<IdentityUser>
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }
    // DbSets del dominio de negocio...
}
La integración con EF Core se registra en Program.cs:
Program.cs
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => { /* ... */ })
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();
AddEntityFrameworkStores<AppDbContext>() indica a Identity que debe usar AppDbContext para persistir todas sus entidades (usuarios, roles, claims, tokens) en las tablas AspNet* dentro de DB_TIENDA_MICHOLO.

Middleware de autenticación

El orden en que se registran los middlewares en Program.cs es estrictamente obligatorio:
Program.cs
app.UseAuthentication(); // ANTES de UseAuthorization
app.UseAuthorization();

UseAuthentication()

Inspecciona la petición entrante en busca de la cookie de sesión, deserializa el ClaimsPrincipal y lo asigna a HttpContext.User. Sin este paso, HttpContext.User siempre aparece como anónimo.

UseAuthorization()

Evalúa los atributos [Authorize] del controlador o la acción usando la identidad ya establecida en HttpContext.User. Si se ejecuta antes de UseAuthentication, el usuario siempre aparece como no autenticado y todos los recursos protegidos denegarían el acceso.
Invertir el orden de estos dos middlewares provocaría que ningún usuario pueda iniciar sesión correctamente, ya que la autorización se evaluaría antes de que la identidad estuviera disponible en el contexto de la petición.

LoginViewModel

El formulario de inicio de sesión está vinculado al siguiente ViewModel, definido en ViewModels/LoginViewModel.cs:
ViewModels/LoginViewModel.cs
public class LoginViewModel
{
    [Required(ErrorMessage = "El correo electrónico es requerido")]
    [EmailAddress(ErrorMessage = "Formato de correo inválido")]
    public string Email { get; set; }

    [Required(ErrorMessage = "La contraseña es requerida")]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    public bool RememberMe { get; set; }
}
CampoTipoValidaciónDescripción
Emailstring[Required], [EmailAddress]Identificador único del usuario; se usa como userName en PasswordSignInAsync
Passwordstring[Required], [DataType(Password)]Contraseña en texto plano; Identity la compara contra el hash almacenado
RememberMeboolNingunaSi es true, se pasa como isPersistent: true a PasswordSignInAsync, generando una cookie persistente

Política de contraseñas

Para facilitar las pruebas durante el desarrollo, la configuración de Identity en Program.cs relaja los requisitos estándar de contraseña:
Program.cs
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    options.Password.RequireDigit = false;
    options.Password.RequireLowercase = false;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireUppercase = false;
    options.Password.RequiredLength = 6;
})
OpciónValor configuradoComportamiento
RequireDigitfalseNo se exige ningún dígito numérico en la contraseña
RequireLowercasefalseNo se exige ninguna letra minúscula
RequireNonAlphanumericfalseNo se exige ningún carácter especial (!, @, #, etc.)
RequireUppercasefalseNo se exige ninguna letra mayúscula
RequiredLength6La contraseña debe tener al menos 6 caracteres
Gracias a esta configuración, las cuentas sembradas por SeedData pueden usar contraseñas simples como admin123 y Vendedor123.
Esta política de contraseñas está pensada exclusivamente para entornos de desarrollo y pruebas. Antes de llevar la aplicación a producción, habilita al menos RequireDigit, RequireUppercase y RequireNonAlphanumeric, y considera aumentar RequiredLength a un mínimo de 8 caracteres para cumplir con buenas prácticas de seguridad.

Roles y usuarios predeterminados

SeedData.Initialize garantiza que los roles y cuentas de prueba existen desde el primer arranque de la aplicación:
UsuarioContraseñaRolPermisos
admin@micholo.comadmin123AdminAcceso total: productos, proveedores, ventas, usuarios, reportes
vendedor@micholo.comVendedor123VendedorAcceso restringido: productos y ventas (sin gestión de proveedores ni usuarios)
La página /Account/AccessDenied se muestra cuando un usuario autenticado intenta acceder a una ruta para la que no tiene el rol requerido. Por ejemplo, un usuario con rol Vendedor que intente visitar /Proveedor/Listar (restringida a Admin) será redirigido a esta página en lugar de recibir un error HTTP 403 genérico.

Build docs developers (and LLMs) love