我有一个使用基于cookie的身份验证的常规应用程序。它的配置是这样的:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication("Login")
.AddCookie("Login", c => {
c.ClaimsIssuer = "Myself";
c.LoginPath = new PathString("/Home/Login");
c.AccessDeniedPath = new PathString("/Home/Denied");
});
}
这适用于我的常规操作:
[Authorize]
public IActionResult Users()
{
return View();
}
但是对于我的ajax请求不能很好地工作:
[Authorize, HttpPost("Api/UpdateUserInfo"), ValidateAntiForgeryToken, Produces("application/json")]
public IActionResult UpdateUserInfo([FromBody] Request<User> request)
{
Response<User> response = request.DoWhatYouNeed();
return Json(response);
}
问题是,当会话过期时,MVC引擎会将操作重定向到登录页面,而我的ajax调用将接收该操作。我希望它返回状态代码401,这样当它是一个ajax请求时,我可以将用户重定向回登录页面。我尝试编写一个策略,但我不知道如何取消设置或使其忽略来自身份验证服务的默认重定向到登录页面。
public class AuthorizeAjax : AuthorizationHandler<AuthorizeAjax>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthorizeAjax requirement)
{
if (context.User.Identity.IsAuthenticated)
{
context.Succeed(requirement);
}
else
{
context.Fail();
if (context.Resource is AuthorizationFilterContext redirectContext)
{
// - This is null already, and the redirect to login will still happen after this.
redirectContext.Result = null;
}
}
return Task.CompletedTask;
}
}
我该怎么做呢?
编辑:经过大量的谷歌搜索,我在2.0版本中发现了这种新的处理方式:
services.AddAuthentication("Login")
.AddCookie("Login", c => {
c.ClaimsIssuer = "Myself";
c.LoginPath = new PathString("/Home/Login");
c.Events.OnRedirectToLogin = (context) =>
{
// - Or a better way to detect it's an ajax request
if (context.Request.Headers["Content-Type"] == "application/json")
{
context.HttpContext.Response.StatusCode = 401;
}
else
{
context.Response.Redirect(context.RedirectUri);
}
return Task.CompletedTask;
};
});
现在它就能工作了!
发布于 2019-03-26 03:47:18
您需要的内容可以通过扩展AuthorizeAttribute类来实现。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
filterContext.Result = new JsonResult
{
Data = new { Success = false, Data = "Unauthorized" },
ContentEncoding = System.Text.Encoding.UTF8,
ContentType = "application/json",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}
然后,您可以在Ajax方法上指定此属性。
希望这能有所帮助。
https://stackoverflow.com/questions/55344665
复制相似问题