【发布时间】:2019-08-16 02:23:19
【问题描述】:
我有一个使用基于 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;
};
});
它现在有效!
【问题讨论】:
-
调用 ajax 请求时发生了什么?你得到 401 还是得到其他异常?
-
检查this 答案。它不适用于核心,但我认为它应该可以工作。
-
@ManojChoudhari 我没有收到任何错误,而是获得了登录页面的 HMTL 代码。
-
我对 AzureAD 有同样的问题,并根据您的回答解决了它 - 请参阅 github.com/aspnet/AspNetCore/issues/7348 - 我修改了 AzureAdAuthenticationBuilderExtensions.cs 2 个不同之处:1)更改 OnRedirectToIdentityProvider 和 2)您需要调用上下文。处理响应();以便将状态码传播给用户。
标签: c# ajax .net-core asp.net-core-mvc