Не могу получить претензии в обработчике авторизации

public class RequestLoginIsUserLoginHandler : AuthorizationHandler<AccessRequirement, string>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AccessRequirement requirement, string resource)
    {
        string? name = context.User.Identity?.Name;
        if (name == resource)
        {
            context.Succeed(requirement);
        }
        return Task.CompletedTask;
    }
}

Я вижу значения утверждений в базе данных, но context.User.Identity?.Name всегда имеет значение null. изображение

Я использую аутентификацию с использованием файлов cookie. Я добавляю претензию следующим образом:

var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, input.Login),
            new Claim(ClaimTypes.Role, "user")
        };
await userManager.AddClaimsAsync(user, claims);

Возможно у меня здесь проблемы:

[HttpPost("/login")]
    public async Task<IActionResult> Login(string login, string password)
    {
        var user = await mediator.Send(new GetUserByLoginQuery(login));
        if (user is null) return Unauthorized("wrong login");

        var result = await signInManager.PasswordSignInAsync(user, password, false, false);
        if (!result.Succeeded) 
        {
            return Unauthorized("wrong password");
        }
        return Ok();
    }

Я пытался использовать ClaimTypes.Name и свой собственный тип «Имя». Результат тот же.

Обновлено. Претензии добавляю при регистрации. Код:

[HttpPost("/register")]
    public async Task<IActionResult> CreateUser(RegisterInput input)
    {
        var userWithSameLogin = await mediator.Send(new GetUserByLoginQuery(input.Login));
        if (userWithSameLogin != null)
        {
            return Conflict();
        }

        var user = new User
        {
            UserName = input.Login,
            FirstName = input.FirstName,
            LastName = input.LastName,
            PhoneNumber = input.PhoneNumber,
            Email = input.Email
        };
        
        var result = await userManager.CreateAsync(user, input.Password);
        if (!result.Succeeded)
        {
            return BadRequest(result.Errors);
        }
        
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, input.Login),
            new Claim(ClaimTypes.Role, "user")
        };
        await userManager.AddClaimsAsync(user, claims);

        return Ok();
    }
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Эта проблема может возникнуть из-за того, что утверждение неправильно прикреплено к субъекту аутентификации или они неправильно загружаются во время процесса аутентификации.

вы можете попробовать приведенный ниже пример кода, чтобы правильно добавить утверждение, поскольку оно не показывает ноль:

Программа.cs:

builder.Services.AddControllersWithViews();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Add Identity services
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

// Configure Cookie Authentication
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.LoginPath = "/Account/Login";
        options.AccessDeniedPath = "/Account/AccessDenied";
    });

Аккаунтконтроллер.cs:

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using CookieAuthDemo1.Models;

namespace CookieAuthDemo1.Controllers
{
    public class AccountController : Controller
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly UserManager<IdentityUser> _userManager;

        public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager)
        {
            _signInManager = signInManager;
            _userManager = userManager;
        }

        [HttpGet]
        public IActionResult Login()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Login(LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            var user = await _userManager.FindByNameAsync(model.Login);
            if (user == null)
            {
                ModelState.AddModelError(string.Empty, "Invalid login.");
                return View(model);
            }

            var result = await _signInManager.PasswordSignInAsync(user, model.Password, false, false);
            if (result.Succeeded)
            {
                var claims = new List<Claim>
           {
               new Claim(ClaimTypes.Name, user.UserName),
               new Claim(ClaimTypes.Role, "user")
           };
                var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                var authProperties = new AuthenticationProperties { IsPersistent = true };

                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);

                return RedirectToAction("Index", "Home");
            }

            ModelState.AddModelError(string.Empty, "Invalid password.");
            return View(model);
        }


        [HttpPost]
        public async Task<IActionResult> Logout()
        {
            await _signInManager.SignOutAsync();
            return RedirectToAction("Index", "Home");
        }
    }
    }

Я добавляю утверждения, используя UserManager<User> во время регистрации (я добавил свой метод CreateUser в текст вопроса). Я обновил свой код, используя ваш способ добавления утверждений, и это сработало. Спасибо. Но я до сих пор не понимаю, почему мой код неприемлем.

Daniil Kozenko 27.08.2024 14:12

@DaniilKozенко, когда вы входите в систему с помощью SignInManager.PasswordSignInAsync, он не включает автоматически все претензии из базы данных в HttpContext.User. По умолчанию он включает только несколько существенных утверждений. Вот почему context.User.Identity?.Name было null — утверждение Name не было включено, если вы явно не добавили его после входа в систему. Заявления, добавленные вами во время регистрации, хранятся в базе данных, но они не прикрепляются автоматически к ClaimsPrincipal во время входа в систему, если вы не извлекаете и не добавляете их вручную.

Jalpa Panchal 28.08.2024 04:33

В моем коде после успешной аутентификации пользователя с помощью SignInManager.PasswordSignInAsync я вручную добавляю утверждения в ClaimsIdentity, а затем подписываю пользователя с этими утверждениями. Это гарантирует, что все необходимые утверждения будут включены в файл cookie аутентификации и будут доступны через HttpContext.User на протяжении всего сеанса пользователя. дайте мне знать, если у вас все еще есть какие-либо вопросы или сомнения

Jalpa Panchal 28.08.2024 04:33

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