AntiForgeryToken Expiration Blank Page

試著忘記壹切 提交于 2019-12-22 03:45:26

问题


I'm using IdentityServer4 with ASP.NET Core 2.2. On the Post Login method I have applied the ValidateAntiForgeryToken. Generally after 20 minutes to 2 hours of sitting on the login page and then attempting to login it produces a blank page.

If you look at Postman Console you get a 400 Bad Request message. I then set the Cookie Expiration on the AntiForgery options to 90 days. I was able to allow the page to sit for up to 6 hours and still login. However, after around 8 hours (overnight), I received the blank page again after attempting to login.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login
services.AddAntiforgery(options =>
{
    options.Cookie.Expiration = TimeSpan.FromDays(90);
});

I expect to be able to sit on the login page for 90 days which is the duration of the cookie but that doesn't work. How do I get the cookie for the AntiforgeryToken to last the entire 90 days or whatever time I set it to and not timeout or expire? Is there a way to catch this error and redirect the user back to the login method?


回答1:


Yet another implementation using the default one including all prechecks, logging etc. And it's still an AuthorizationFilter, so that prevents any further action execution. The only difference is that it triggers HttpGet to the same url instead of the default 400 response, a kind of the Post/Redirect/Get pattern implementation.

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);
        }
    }
}



回答2:


This was my final solution. I added a attribute using the IAntifogery dependency injection.

public class CustomValidationAttribute : ActionFilterAttribute
{
    private IAntiforgery _antiForgery { get; }

    public CustomValidationAttribute(IAntiforgery antiforgery)
    {
        _antiForgery = antiforgery;
    }

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var isRequestValid = await this._antiForgery.IsRequestValidAsync(context.HttpContext);
        if (!isRequestValid)
        {
            //Add Code here if token is not valid

            return;         
        }

        await next();
    }
}

Add the attribute to your controller methods that also use [HttpPost]

[TypeFilter(typeof(CustomValidationAttribute))]



回答3:


Slight modification to d_f code https://stackoverflow.com/a/56383473/841898 Instead of page redirect we just add error to ModelState. Then we display in model state summary.

public class CustomAntiForgeryTokenAttribute : TypeFilterAttribute
{
    public CustomAntiForgeryTokenAttribute() : 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)
        {
            ctx.ModelState.AddModelError("Token", "Validation Token Expired. Please try again");
            ctx.Result = null;

        }
    }
}


来源:https://stackoverflow.com/questions/56295076/antiforgerytoken-expiration-blank-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!