ASP.NET Ядро 3.1 В доступе MVC отказано в авторизации на основе ролей — конфликт с пользовательской базой данных UserClaimsPrincipalFactory

#asp.net #asp.net-mvc #asp.net-core #asp.net-identity #asp.net-core-3.1

#asp.net #asp.net-mvc #asp.net-core #asp.net-identity #asp.net-core-3.1

Вопрос:

Я прочитал много ответов на stackoverflow для подобных проблем, но все еще не могу понять, что я делаю неправильно.

Мои таблицы AspNetUsers, AspNetRoles и AspNetUserRoles были заполнены правильно.

Это мои конфигурационные сервисы:

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseLazyLoadingProxies().UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = false)
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddClaimsPrincipalFactory<CustomUserClaimsPrincipalFactory>();
        services.AddControllersWithViews();
        services.AddMvc();
        services.AddRazorPages();
        services.AddAuthorization(options => {
            options.AddPolicy("ManagerOnly", policy => policy.RequireRole("Manager"));
            options.FallbackPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
        });
        services.Configure<IdentityOptions>(options =>
        {
            ...
        });

        services.ConfigureApplicationCookie(options =>
        {
            ...
        });

        services.Configure<PasswordHasherOptions>(option =>
        {
            ...
        });
    }
  

Я использую управление идентификацией по умолчанию, которое поддерживает Visual Studio, когда мы выбираем «индивидуальные учетные записи пользователей» в качестве метода аутентификации.

Когда я выполняю [Authorize(Policy = "ManagerOnly"] какое-либо действие, я получаю результат отказа в доступе, даже при входе в систему с правильной учетной записи пользователя, которая находится в роли менеджера.

Редактировать:

Я убедился, что проблема исчезает при удалении .AddClaimsPrincipalFactory<CustomUserClaimsPrincipalFactory>();

Ниже приведен мой пользовательский userclaimsprincipalfactory:

 public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser>
{
    public CustomUserClaimsPrincipalFactory(
    UserManager<ApplicationUser> userManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor)
    {
    }

    protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
    {
        var identity = await base.GenerateClaimsAsync(user);
        identity.AddClaim(new Claim("FullName", user.FullName ?? "Unnamed"));
        return identity;
    }
}
  

Есть идеи, почему это будет конфликтовать с ролями?

ПРАВКА 2:

Решение для новичков вроде меня:

 public class CustomUserClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    public CustomUserClaimsPrincipalFactory(
    UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
    {
    }
  

Насколько я понимаю, диспетчер ролей должен быть введен в пользовательскую фабрику утверждений, чтобы роли, определенные в базе данных, могли быть загружены, когда мы переопределяем генерацию базовых утверждений.

Комментарии:

1. возможно, вам следует попробовать протоколировать, чтобы помочь вам отладить, действительно ли роли правильные (извлечены и возвращены). Вероятно, хорошей идеей будет абстрагировать вашу политику с помощью обработчика, чтобы вы могли на самом деле издеваться и тестировать ее.

2. @PmanAce пожалуйста, ознакомьтесь с обновленным вопросом, если у вас есть время

3. обнаружены ли ваши роли в вашем удостоверении после вызова базовых утверждений о генерации?

4. @PmanAce Нет, это не так. Я не понимаю, почему. Почему роль не выбирается из базы данных? Почему выбрана роль, когда я не использую пользовательскую фабрику утверждений?

5. @PmanAce спасибо, что привели меня к решению. Пожалуйста, добавьте это в качестве ответа, чтобы я мог пометить его как правильный. Я добавил RoleManager<IdentityRole> roleManager в конструктор пользовательской фабрики, и это устранило проблему.

Ответ №1:

Я думаю, что ваши зависимости, которые вы вводите в CustomUserClaimsPrincipalFactory, каким-то образом отличаются или не разрешены должным образом, поэтому не подключаются к БД.

Пожалуйста, убедитесь, что диспетчер ролей правильно настроен в вашем автозагрузчике.