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 void
por 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:
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.