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();
当我改变这两个的顺序时,它起作用了。
我正在尝试使用 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();
当我改变这两个的顺序时,它起作用了。