在具有基于Cookie的授权的asp.net核心3.1 Web应用程序中,我创建了一个自定义验证程序,该验证程序将在Cookie授权的OnValidatePrincipal事件上执行。验证程序会做一些事情,其中之一是在后端检查用户是否被阻止。如果用户被阻止,则根据MS文档,执行CookieValidatePrincipalContext.RejectPrincipal()
方法,并使用CookieValidatePrincipalContext.HttpContext.SignOutAsyn(...)
方法注销用户。
这里是验证器的相关代码:
public static async Task ValidateAsync(CookieValidatePrincipalContext cookieValidatePrincipalContext)
{
var userPrincipal = cookieValidatePrincipalContext.Principal;
var userService = cookieValidatePrincipalContext.GetUserService();
var databaseUser = await userService.GetUserBySidAsync(userPrincipal.GetSidAsByteArray());
if (IsUserInvalidOrBlocked(databaseUser))
{
await RejectUser(cookieValidatePrincipalContext);
return;
}
else if (IsUserPrincipalOutdated(userPrincipal, databaseUser))
{
var updatedUserPrincipal = await CreateUpdatedUserPrincipal(userPrincipal, userService);
cookieValidatePrincipalContext.ReplacePrincipal(updatedUserPrincipal);
cookieValidatePrincipalContext.ShouldRenew = true;
}
}
private static bool IsUserInvalidOrBlocked(User user)
=> user is null || user.IsBlocked;
private static async Task RejectUser(CookieValidatePrincipalContext context)
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
这是基于cookie的授权的设置:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(co =>
{
co.LoginPath = @$"/{ControllerHelpers.GetControllerName<AuthenticationController>()}/{nameof(AuthenticationController.Login)}";
co.LogoutPath = @$"/{ControllerHelpers.GetControllerName<AuthenticationController>()}/{nameof(AuthenticationController.Logout)}";
co.ExpireTimeSpan = TimeSpan.FromDays(30);
co.Cookie.SameSite = SameSiteMode.Strict;
co.Cookie.Name = "GioBQADashboard";
co.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = UserPrincipalValidator.ValidateAsync
};
co.Validate();
});
实际上是按预期方式调用和执行的,并在用户被阻止后导航到新页面时将其重定向到登录页面。
大多数视图都有对api方法的ajax调用,这些方法每10秒在计时器上执行一次。对于这些呼叫,凭据也将得到验证,并且用户将注销。但是,在用户注销后,页面上会出现一个弹出窗口,要求用户提供凭据:
如果用户未输入其凭据并导航到另一个页面,则他们将按预期进入登录页面。如果他们输入了凭据,则他们将保持登录状态,但是其身份似乎是其Windows身份...这里发生了什么?我真正想要实现的是让用户在注销后进入登录页面以进行任何请求。
我显然配置错误,因此基于cookie的授权对于ajax请求无法正常工作,但是我无法弄清楚它是什么。还是授权属性无法按我期望的方式工作?
代码行对我来说很好。
此登录对话框似乎是Windows身份验证的默认对话框。通常,它来自launchSettings.json文件中的iisSettings。在Visual Studio中,您可以在“项目”>“属性”> launchSettings.json
中找到后者。将windowsAuthentication设置为false。
{
"iisSettings": {
"windowsAuthentication": false,
}
}