我将IdentityServer4与ASP.NET Core 2.2一起使用。在Post Login方法上,我应用了ValidateAntiForgeryToken。通常,在坐在登录页面上20分钟到2个小时之后,尝试登录时会生成空白页面。
如果您查看Postman Console,则会收到一条400错误的请求消息。然后,我将AntiForgery选项上的Cookie有效期设置为90天。我能够让该页面坐满6个小时,并且仍然可以登录。但是,大约8个小时(过夜)后,尝试登录后我又收到了空白页。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login
services.AddAntiforgery(options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(90);
});
我希望能够在登录页面上停留90天,这是cookie的持续时间,但这是行不通的。如何获得AntiforgeryToken的cookie可以持续整整90天或我设置的任何时间,而不是超时或过期?有没有办法捕获此错误并将用户重定向回登录方法?
最佳答案
更新'2021
自ASP.Net Core 3.0 MS以来,decided成为ValidateAntiforgeryTokenAuthorizationFilter
内部。现在,我们必须复制粘贴their code,以便能够派生。但是最有可能我们不需要这样做。为了仅更改结果行为,我们需要的是测试IAntiforgeryValidationFailedResult
的上下文并按照此example中所述进行一致的处理。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Core.Infrastructure;
using Microsoft.AspNetCore.Mvc.Filters;
namespace BasicWebSite.Filters
{
public class RedirectAntiforgeryValidationFailedResultFilter : IAlwaysRunResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
if (context.Result is IAntiforgeryValidationFailedResult result)
{
context.Result =
new RedirectResult("http://example.com/antiforgery-redirect");
}
}
public void OnResultExecuted(ResultExecutedContext context)
{ }
}
}
然后在 Controller 内:// POST: /Antiforgery/LoginWithRedirectResultFilter
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[TypeFilter(typeof(RedirectAntiforgeryValidationFailedResultFilter))]
public string LoginWithRedirectResultFilter(LoginViewModel model)
{
return "Ok";
}
最初的答案涵盖.net core 2.2另一种使用默认方法的实现,包括所有预检查,日志记录等。它仍然是
AuthorizationFilter
,因此可以防止进一步执行操作。唯一的区别是,它将HttpGet
触发到相同的URL,而不是默认的400响应(一种Post/Redirect/Get模式实现)。public class AnotherAntiForgeryTokenAttribute : TypeFilterAttribute
{
public AnotherAntiForgeryTokenAttribute() : base(typeof(AnotherAntiforgeryFilter))
{
}
}
public class AnotherAntiforgeryFilter:ValidateAntiforgeryTokenAuthorizationFilter,
IAsyncAuthorizationFilter
{
public AnotherAntiforgeryFilter(IAntiforgery a, ILoggerFactory l) : base(a, l)
{
}
async Task IAsyncAuthorizationFilter.OnAuthorizationAsync(
AuthorizationFilterContext ctx)
{
await base.OnAuthorizationAsync(ctx);
if (ctx.Result is IAntiforgeryValidationFailedResult)
{
// the next four rows are optional, just illustrating a way
// to save some sensitive data such as initial query
// the form has to support that
var request = ctx.HttpContext.Request;
var url = request.Path.ToUriComponent();
if (request.Form?["ReturnUrl"].Count > 0)
url = $"{url}?ReturnUrl={Uri.EscapeDataString(request.Form?["ReturnUrl"])}";
// and the following is the only real customization
ctx.Result = new LocalRedirectResult(url);
}
}
}
关于c# - AntiForgeryToken到期空白页,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56295076/