Saltar al contenido

ASP.NET Core Identity 2: User.IsInRole siempre devuelve false

Esta crónica ha sido aprobado por expertos así aseguramos la veracidad de nuestra esta crónica.

Solución:

Entonces, para recapitular, la pregunta es por qué el código proporcionado por la plantilla de la aplicación web principal de ASP.NET no carga roles o notificaciones de roles en la cookie cuando un usuario inicia sesión.

Después de mucho buscar en Google y experimentar, parece que hay dos modificaciones que se deben realizar en el código de la plantilla para que funcionen las funciones y los reclamos de funciones:

Primero, debe agregar la siguiente línea de código en Startup.cs para habilitar RoleManager. (Este poco de magia se mencionó en el OP).

services.AddDefaultIdentity()
   .AddRoles() // <-- Add this line
    .AddEntityFrameworkStores();

¡Pero espera hay mas! De acuerdo con esta discusión en GitHub, hacer que los roles y las notificaciones aparezcan en la cookie implica o volviendo a la service.AddIdentity código de inicialización, o seguir con service.AddDefaultIdentity y agregando esta línea de código a ConfigureServices:

// Add Role claims to the User object
// See: https://github.com/aspnet/Identity/issues/1813#issuecomment-420066501
services.AddScoped, UserClaimsPrincipalFactory>();

Si lee la discusión a la que se hace referencia anteriormente, verá que los roles y los reclamos de roles aparentemente están en desuso, o al menos no se admiten con entusiasmo. Personalmente, encuentro muy útil asignar notificaciones a funciones, asignar funciones a usuarios y luego tomar decisiones de autorización basadas en las notificaciones (que se otorgan a los usuarios en función de sus funciones). Esto me brinda una manera fácil y declarativa de permitir, por ejemplo, que múltiples roles accedan a una función (es decir, todos los roles que contienen el reclamo utilizado para habilitar esa función).

Pero SÍ desea prestar atención a la cantidad de datos de roles y reclamos que se transportan en la cookie de autenticación. Más datos significan más bytes enviados al servidor con cada solicitud, y no tengo ni idea de lo que sucede cuando te topas con algún tipo de límite en el tamaño de la cookie.

Ahh, hay algunos cambios de ASP.NET Core versión 2.0 a 2.1. AddDefaultIdentity es el.

No sé por dónde empezar con su código, por lo tanto, proporcionaré un ejemplo para crear y obtener roles de usuario.

Vamos a crear UserRoles primero:

public enum UserRoles

    [Display(Name = "Quản trị viên")]
    Administrator = 0,

    [Display(Name = "Kiểm soát viên")]
    Moderator = 1,

    [Display(Name = "Thành viên")]
    Member = 2

Nota: Puede quitar el attribute Display.

Luego, creamos RolesExtensions clase:

public static class RolesExtensions

    public static async Task InitializeAsync(RoleManager roleManager)
    
        foreach (string roleName in Enum.GetNames(typeof(UserRoles)))
        
            if (!await roleManager.RoleExistsAsync(roleName))
            
                await roleManager.CreateAsync(new IdentityRole(roleName));
            
        
    

A continuación, en el Startup.cs clase, lo ejecutamos:

    public void Configure(
        IApplicationBuilder app, 
        IHostingEnvironment env, 
        RoleManager roleManager)
    
        // other settings...

        app.UseMvc(routes =>
        
            routes.MapRoute(
                name: "default",
                template: "controller=Home/action=Index/id?");
        );

        var task = RolesExtensions.InitializeAsync(roleManager);
        task.Wait();
    

Nota: Configure requiere un tipo devuelto voidpor lo que necesitamos crear una tarea para inicializar los roles de usuario y llamamos Wait método.

No cambie el tipo devuelto de esta manera:

public async void Configure(...)

    await RolesExtensions.InitializeAsync(roleManager);

Fuente: Async/Await – Mejores prácticas en programación asíncrona

En el ConfigureServices método, estas configuraciones NO trabaja (no podemos usar User.IsInRole correctamente):

services.AddDefaultIdentity()
    //.AddRoles()
    //.AddRoleManager>()
    .AddEntityFrameworkStores();

no se porque pero AddRoles y AddRoleManager no es compatible para verificar el rol de un usuario (User.IsInRole).

En este caso, necesitamos registrar un servicio como este:

services.AddIdentity()
    .AddEntityFrameworkStores();

De esta manera, creamos 3 roles de usuario en la base de datos:

1

Cuando registre un nuevo usuario, solo tenemos que llamar:

await _userManager.AddToRoleAsync(user, nameof(UserRoles.Administrator));

Finalmente, podemos usar [Authorize(Roles = "Administrator")] y:

if (User.IsInRole("Administrator"))

    // authorized


// or
if (User.IsInRole(nameof(UserRoles.Administrator)))

    // authorized


// but
if (User.IsInRole("ADMINISTRATOR"))

    // authorized

P/D: Hay muchas cosas que deben implementarse para lograr este objetivo. Así que tal vez me perdí algo en este ejemplo.

Sección de Reseñas y Valoraciones

Nos encantaría que puedieras dar recomendación a esta reseña si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *