在.NET Core MVC中使用Ajax处理会话超时

时间:2019-03-25 18:52:39

标签: c# ajax .net-core asp.net-core-mvc

我有一个使用基于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;
                   };                       
        });

现在就可以使用!

1 个答案:

答案 0 :(得分:0)

您可以通过扩展AuthorizeAttribute类来实现。

1234

然后可以在Ajax方法上指定此属性。

希望这会有所帮助。

参考:http://benedict-chan.github.io/blog/2014/02/11/asp-dot-net-mvc-how-to-handle-unauthorized-response-in-json-for-your-api/