У меня есть обычное приложение, использующее 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;
};
});
И сейчас он работает!