ASP.NET 无法实施 Authentication/Authorization

ASP.NET Can't Implement Authentication/Authorization

我正在尝试使用 Identity 在 .NET 5 中创建一个基本的 WebApp。我实现了 Database、Repos、API 等,并且 Identity(extended) 没有问题。现在,我想使用 cookie 和 IdentityRole 实现一个登录系统。

我正在使用 signInManager.PasswordSignIn 登录用户,并且我毫无问题地获得了一个 cookie。但是,当我尝试从控制器请求授权调用时,即使用户具有 [Authorize] 注释中指定的角色,我也会被重定向到登录路径。

在这里你可以看到我在请求登录后得到的 cookie,我可以得到所有用户,因为该请求没有 [Authorize] 注释。

SignIn Response

Identity Cookie

但是当我尝试访问特定用户时,我得到 401,因为 GetUser(id) 具有 [Authorize(Roles = "User")] 作为注释,即使我的用户具有“用户”角色。

401 on GET

AspNetRoles Table

AspNetUserRoles Table

Id of FirstUser and UserId in UserRoles matches, so I am not logged in on wrong user

我做错了什么?

Startup.cs

//ConfigureServices
services.AddIdentity<User, IdentityRole>(config => {
    config.SignIn.RequireConfirmedEmail = false;
})
  .AddEntityFrameworkStores<FoodDonationContext>()
  .AddDefaultTokenProviders();

services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
    builder.WithOrigins("http://localhost:3000")
    .AllowAnyMethod()
    .AllowAnyHeader()
    .AllowCredentials();
}));
            
services.ConfigureApplicationCookie(options =>
{
    options.AccessDeniedPath = "/TEST1"; //These TEST redirections are for debbugging
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = new TimeSpan(1, 0, 0);
    options.LoginPath = "/TEST2";
    options.LogoutPath = "/TEST3";
    options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
    options.SlidingExpiration = true;
    options.Events.OnRedirectToLogin = context =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return Task.CompletedTask;
    };
});

//Configure
app.UseRouting();
app.UseHttpsRedirection();
app.UseCors("MyPolicy");
            

app.UseCookiePolicy(new CookiePolicyOptions
{
    Secure = CookieSecurePolicy.None
});

app.UseAuthorization();
app.UseAuthentication();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

UserController.cs

[Route("api/[controller]")]
[ApiController]
public class UserController : Controller
{
    private readonly IUserRepo _repository;
    private readonly IMapper _mapper;
    private readonly UserManager<User> _userManager;
    private readonly SignInManager<User> _signInManager;

    public UserController(IUserRepo repository, IMapper mapper, UserManager<User> userManager, SignInManager<User> signInManager)
    {
        _repository = repository;
        _mapper = mapper;
        _userManager = userManager;
        _signInManager = signInManager;
    }

    [HttpPost("signin")]
    public async Task<ActionResult> SignInUser(UserSignInDTO signInData)
    {
        var user = await _repository.GetUserWithUserNameAsync(signInData.UserName);
        if (user != null)
        {
            var result = await _signInManager.PasswordSignInAsync(user, signInData.Password, false, false);
            if (result.Succeeded)
            {
                RedirectToRoute("/TEST5");
                return Ok(result);
            }
            else
                return BadRequest();
            }

        return NotFound();
    }

    [Authorize(Roles = "User")]
    [HttpGet("{id}", Name = "GetUser")]
    public async Task<ActionResult<UserReadDTO>> GetUser(string id)
    {
        var user = await _repository.GetUserAsync(id);
        if (user != null)
        {
            user.Age = DateTime.Now.Subtract(user.BirthdayDate).Days / 365;
            _repository.SaveChangesAsync();

            return Ok(_mapper.Map<UserReadDTO>(user));
        }
            return NotFound();
        }

    [HttpGet(Name = "GetAllUsers")]
    public async Task<ActionResult<IEnumerable<UserReadDTO>>> GetAllUsers()
    {
        var userList = await _repository.GetAllUsersAsync();
        if (userList != null)
        {
            foreach (var user in userList) {
                user.Age = DateTime.Now.Subtract(user.BirthdayDate).Days / 365;
            }
        _repository.SaveChangesAsync();

        return Ok(_mapper.Map<IEnumerable<UserReadDTO>>(userList));
       }
       return NotFound();
    }
}
app.UseAuthorization();
app.UseAuthentication();

当我改变这两个的顺序时,它起作用了。