.net core identity 2.1 авторизация роли не работает

Я реализовал аутентификацию на основе ролей несколько раз до версии 2.1. Выполнил шаги, чтобы создать новую идентичность 2.1.

Я расширил модель IdentityUser, добавив дополнительные поля, логин работает нормально, новые поля присутствуют.

Службы настройки startup.cs содержат

         services.AddDefaultIdentity<AppUser>()
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

Я посеял роли

         IdentityRole role = new IdentityRole();
         role.Name = "Administrator";
         IdentityResult roleResult = roleManager.
         CreateAsync(role).Result;

Затем создал пользователя и добавил в роль

        AppUser user = new AppUser();
        user.UserName = "Admin";
        user.Email = "[email protected]";
        user.Name = "Administrator";
        user.LockoutEnabled = false;
        user.EmailConfirmed = true;

        IdentityResult result = userManager.CreateAsync(user, "password").Result;

        if (result.Succeeded)
        {
            userManager.AddToRoleAsync(user, "Administrator").Wait();
        }

Все прошло успешно, и база данных выглядит нормально (у AspNetUserRoles есть ссылки)

Однако добавление к контроллеру роли всегда будет возвращать не авторизованный

       [Authorize(Roles = "Administrator")]

Но простая проверка входа в систему с [Authorize] (без роли) будет работать.

Как я могу это исправить / какой самый простой способ включить исходный код, чтобы я мог пройти / отладить теги [Authorize]?

Для отладки, возможно, вы можете использовать [Авторизовать] и добавить где-нибудь в методе действия: var Claims = User.Claims; Итак, вы можете увидеть, действительно ли претензии есть

Marcel 27.09.2018 01:26

У вас настроены файлы cookie?

mvermef 27.09.2018 06:57
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
2
10 849
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Как исправить

However, decorating a controller with a role will always return not authorized

  [Authorize(Roles = "Administrator")]

Это известная ошибка в версии 2.1. См. проблема здесь.

Следую совету использования старого API, предложенного HaoK и C-BERBER, и теперь он работает безотказно.

Вот мой DbContext:

public class ApplicationDbContext : IdentityDbContext<AppUser,IdentityRole,string>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Настройте удостоверение с помощью API старого стиля:

services.AddIdentity<AppUser, IdentityRole>()
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddDefaultUI()
        .AddDefaultTokenProviders()
        .AddEntityFrameworkStores<ApplicationDbContext>();

Наконец, выйти и повторно войти, теперь он будет работать, как ожидалось.

Как отлаживать исходный код

Думаю, вам не захочется отлаживать сам AuthorizeAttribe, поскольку он обрабатывается во время компиляции. Если вы хотите отладить AuthorizeFilter, вы можете выполнить следующие шаги:

нажмите Tools -> Options -> Debugging

  1. в General, отменить выбор в Enable Just My Code в Visual Studio
  2. выберите Enable Source Link Support
  3. в Symbols убедитесь, что выбран Серверы Microsoft Symbol

И теперь вы можете отлаживать исходный код. Однако из-за того, как работает этот фильтр, вам нужно установить точку останова перед MVC. Я просто установил фиктивное промежуточное ПО, которое будет выполняться перед обработчиком маршрутизатора MVC:

Скриншот отладки AuthorizeFiler:

Я добавил роль в претензии. Тогда он работает как для UI (HttpContext.User.IsInRole("Admin")), так и для атрибута authorize ([Authorize(Roles = "Admin")]).

Файл Startup.cs:

public void ConfigureServices(IServiceCollection services)
{    
    services.AddIdentity<ApplicationUser, IdentityRole>()                
      .AddEntityFrameworkStores<WandContext>();
    ///..... other code
} 

Во время аутентификации я добавляю роль в свою заявку.

var invalidLoginAttempt = false;
var user = await _userManager.FindByNameAsync(loginModel.Email);
if (user != null)
{
    var result = await _signInManager.CheckPasswordSignInAsync(user, loginModel.Password, lockoutOnFailure: true);

    if (result.Succeeded)
    {                                       
        var customClaims = new List<Claim>
        {
            new Claim(ClaimTypes.Role, Role.Admin)
        };

        var claimsIdentity = new ClaimsIdentity(customClaims, CookieAuthenticationDefaults.AuthenticationScheme);
        var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

        await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme,
            claimsPrincipal, new AuthenticationProperties { IsPersistent = loginModel.RememberMe });

        return LocalRedirect(returnUrl);
    }
    else if (result.IsLockedOut)
        ModelState.AddModelError(string.Empty, "This account has been locked out, please try again later.");
    else
        invalidLoginAttempt = true;
}
else
    invalidLoginAttempt = true;

В моем случае ASP.NET Core 3 (предварительная версия) + Angular решение было в AddAuthentication

services.AddDefaultIdentity<ApplicationUser>()
    .AddRoles<IdentityRole>()
    .AddRoleManager<RoleManager<IdentityRole>>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
    options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
    options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
});

Другие вопросы по теме