我使用的是托管的Blazor WebAssembly项目模板,在设置cookie作为主要身份验证方法(也用于API(后,一切都很好,直到我更改了一行代码(前端或后端(,自动编译开始,网页被重新加载(多亏了"无调试启动"(,但这一次authcookie似乎无效,我似乎不再登录。
有没有办法阻止这种行为?或者阻止cookie身份验证在不同编译之间更改的方法?
以下是我的CookieAuthenticationEvents实现/覆盖:
public class CookieAuth : CookieAuthenticationEvents
{
readonly IUserService UserRepository;
public CookieAuth(IUserService userRepository)
{
UserRepository = userRepository;
}
public override Task RedirectToLogin(RedirectContext<CookieAuthenticationOptions> context)
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
public override Task RedirectToAccessDenied(RedirectContext<CookieAuthenticationOptions> context)
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
var userId = (from c in userPrincipal.Claims
where c.Type == ClaimTypes.NameIdentifier
select c.Value).FirstOrDefault();
var isTeacherAndBlocked = await UserRepository.IsTeacherAndIsBlocked(userId);
if (isTeacherAndBlocked)
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return;
}
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (!DateTime.TryParse(lastChanged, out DateTime lastChangedDate))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return;
}
if (!await UserRepository.ValidateLastChanged(lastChanged, userId))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
同时,UserRepository.ValidateLastChanged(...)
检查获得的日期字符串是否与DB中的日期字符串匹配(这是一种计算用户是否更改了密码,然后从另一个设备转到旧会话的方法,在这种情况下,我希望这种会话无效(
然后是常见的Startup.cs
cookie配置:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromHours(1);
options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.Name = "wtf";
options.EventsType = typeof(CookieAuth);
options.SlidingExpiration = true;
});
Nevermind发现这是日期作为字符串之间的比较问题,只是不要这样做,用记号。:D