我将 IdentityServer4 与 ASP.NET Core 2.2 一起使用。在“登录后”方法中,我应用了 ValidateAntiForgeryToken。通常,在登录页面停留 20 分钟到 2 小时后尝试登录,会出现一个空白页面。
如果您查看 Postman Console,您会收到 400 Bad Request 消息。然后,我将 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 https://github.com/dotnet/aspnetcore/issues/22947使ValidateAntiforgeryTokenAuthorizationFilter
内部的。现在我们必须复制粘贴他们的代码 https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/Mvc.ViewFeatures/src/Filters/ValidateAntiforgeryTokenAuthorizationFilter.cs,能够推导出来。但很可能我们不需要。要改变结果行为,我们需要的只是测试上下文IAntiforgeryValidationFailedResult
并按照本中所述进行相应操作example https://github.com/dotnet/aspnetcore/blob/master/src/Mvc/test/WebSites/BasicWebSite/Filters/RedirectAntiforgeryValidationFailedResultFilter.cs.
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)
{ }
}
}
然后在控制器内:
// POST: /Antiforgery/LoginWithRedirectResultFilter
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
[TypeFilter(typeof(RedirectAntiforgeryValidationFailedResultFilter))]
public string LoginWithRedirectResultFilter(LoginViewModel model)
{
return "Ok";
}
原始答案涵盖.net core 2.2
另一种实现使用默认的实现,包括所有预检查、日志记录等。它仍然是一个AuthorizationFilter
,从而阻止任何进一步的操作执行。唯一的区别是它会触发HttpGet
到相同的 url 而不是默认的 400 响应,这是一种发布/重定向/获取模式实施。
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);
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)