我有以下两个方案:
builder.Services.AddAuthentication(option =>
{
option.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
option.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(option => // Admins' Scheme
{
option.LoginPath = new PathString("/admin/auth/login");
option.ExpireTimeSpan = TimeSpan.FromMinutes(1);
option.AccessDeniedPath = new PathString("/");
}).AddCookie("user", option => // Users' Scheme
{
option.LoginPath = new PathString("/");
option.ExpireTimeSpan = TimeSpan.FromMinutes(1);
option.AccessDeniedPath = new PathString("/");
});
用户有两种方式访问登录功能:管理员和普通用户。
对于管理员:
[HttpPost]
public IActionResult Login(RequestAuthLoginUsersServiceDto req)
{
var login = _userFacade.AuthLoginUsersService.Execute(req);
if (login != null)
{
if (login.IsSuccess)
{
var claims = new List<Claim>() {
new Claim(ClaimTypes.NameIdentifier,login.Data.IdUser.ToString()),
new Claim(ClaimTypes.Email,req.Email),
new Claim(ClaimTypes.Name,login.Data.Nickname),
new Claim(ClaimTypes.Role,login.Data.Role),
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var propertise = new AuthenticationProperties()
{
IsPersistent = true,
ExpiresUtc = DateTime.Now.AddYears(1),
};
_userLoginLogFacade.PostUserLoginLogService.Execute(new RequestPostUserLoginLogServiceDto
{
UsersId = login.Data.IdUser,
IP = Request.HttpContext.Connection.RemoteIpAddress.ToString(),
});
HttpContext.SignInAsync(principal, propertise);
}
}
return Json(login);
}
用户:
[HttpPost]
public IActionResult Login(RequestAuthLoginUsersServiceDto req)
{
var login = _userFacade.AuthLoginUsersService.Execute(req);
if (login != null)
{
if (login.IsSuccess)
{
var claims = new List<Claim>() {
new Claim(ClaimTypes.NameIdentifier,login.Data.IdUser.ToString()),
new Claim(ClaimTypes.Email,req.Email),
new Claim(ClaimTypes.Name,login.Data.Nickname),
new Claim(ClaimTypes.Role,login.Data.Role),
};
// var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var identity = new ClaimsIdentity(claims, "user");
var principal = new ClaimsPrincipal(identity);
var propertise = new AuthenticationProperties()
{
IsPersistent = true,
ExpiresUtc = DateTime.Now.AddYears(1),
};
_userLoginLogFacade.PostUserLoginLogService.Execute(new RequestPostUserLoginLogServiceDto
{
UsersId = login.Data.IdUser,
IP = Request.HttpContext.Connection.RemoteIpAddress.ToString(),
});
HttpContext.SignInAsync(
"user",
principal,
propertise);
}
}
问题是当用户登录时,“User.Identity.IsAuthenticated”返回“false”。但是,当管理员登录时,相同的代码将返回“true”。需要注意的是,如果我使用“[Authorize(AuthenticationSchemes = "user")]”,代码将为用户返回“true”。但是,对于默认模式(管理员方式),不需要“[Authorize(AuthenticationSchemes = "user")]”。
现在有一个可能的问题:
option.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
这意味着只有这个管理处理程序才会验证传入的请求,问题是用户 cookie 处理程序发出的身份验证 cookie 是否可以由管理 cookie 的处理程序解码?
我最近深入研究了这一点,发出的 cookie 只能由最初发出 cookie 的同一处理程序读取。这是因为保护 cookie 时使用的“目的”字符串包含“方案”名称。喜欢
Performing protect operation to key {...} with purposes (
- 'C:\code\Data Protection API - Demo project\Data Protection API - Start project\',
- 'Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware',
- 'cookie',
- 'v2').
我还将日志级别设置为详细/跟踪以查看身份验证系统所说的内容。
顺便说一句,我在 https://nestenius.se/
收到了一些有关解决身份验证问题的博客文章