gpt4 book ai didi

asp.net-mvc - 我将如何编写一个 Action 过滤器来确保每个 Post 操作都使用防伪 token ?

转载 作者:行者123 更新时间:2023-12-03 17:49:53 25 4
gpt4 key购买 nike

我想用AntiForgeryTokens在每个 HttpPost 操作上使用名为 ControllerBase 的 Controller 中的 ActionFilter每个其他 Controller 都继承自。

我想通过创建一个继承自 ValidateAntiForgeryToken 的 ActionFilter 来做到这一点。它接受一个参数,告诉它要应用哪些 HTTP 动词。然后我想在 ControllerBase 上应用该过滤器确保AntiForgeryToken检查整个站点上的每个 POST 操作。

我正在考虑使用 this solution , 但

  • AuthorizationContext Constructor (ControllerContext)是一个过时的构造函数,我不确定如何使用推荐的 AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 重建代码。 .
  • 默认情况下它似乎不使用 AntiForgeryToken,因为我收到以下错误:A required anti-forgery token was not supplied or was invalid在每次发布操作之后。

  • 我应该如何重写我的 ActionFilter 以满足当前的非过时标准并在每个 [HttpPost] 上正确使用防伪 token 动词?

    我自己是否必须在每种形式中都包含一个防伪 token (我想我这样做了)? (与自动生成相反 - 不要笑,我很好奇) 更新:正如评论中指出的那样;是的,这必须对每种表格都进行。

    这是我的 ControllerBase 中的代码以供引用:
    [UseAntiForgeryTokenOnPostByDefault]
    public class ControllerBase : Controller
    {
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class BypassAntiForgeryTokenAttribute : ActionFilterAttribute
    {
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class UseAntiForgeryTokenOnPostByDefault : ActionFilterAttribute
    {
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
    if (ShouldValidateAntiForgeryTokenManually(filterContext))
    {
    var authorizationContext = new AuthorizationContext(filterContext.Controller.ControllerContext);

    //Use the authorization of the anti forgery token,
    //which can't be inhereted from because it is sealed
    new ValidateAntiForgeryTokenAttribute().OnAuthorization(authorizationContext);
    }

    base.OnActionExecuting(filterContext);
    }

    /// <summary>
    /// We should validate the anti forgery token manually if the following criteria are met:
    /// 1. The http method must be POST
    /// 2. There is not an existing [ValidateAntiForgeryToken] attribute on the action
    /// 3. There is no [BypassAntiForgeryToken] attribute on the action
    /// </summary>
    private static bool ShouldValidateAntiForgeryTokenManually(ActionExecutingContext filterContext)
    {
    var httpMethod = filterContext.HttpContext.Request.HttpMethod;

    //1. The http method must be POST
    if (httpMethod != "POST") return false;

    // 2. There is not an existing anti forgery token attribute on the action
    var antiForgeryAttributes =
    filterContext.ActionDescriptor.GetCustomAttributes(typeof (ValidateAntiForgeryTokenAttribute), false);

    if (antiForgeryAttributes.Length > 0) return false;

    // 3. There is no [BypassAntiForgeryToken] attribute on the action
    var ignoreAntiForgeryAttributes =
    filterContext.ActionDescriptor.GetCustomAttributes(typeof (BypassAntiForgeryTokenAttribute), false);

    if (ignoreAntiForgeryAttributes.Length > 0) return false;

    return true;
    }
    }
    }

    最佳答案

    我使用了以下方法:

    public class SkipCSRFCheckAttribute : Attribute
    {
    }

    public class AntiForgeryTokenFilter : IAuthorizationFilter
    {
    public void OnAuthorization(AuthorizationContext filterContext)
    {
    if (IsHttpPostRequest(filterContext) && !SkipCsrfCheck(filterContext))
    AntiForgery.Validate();
    }

    private static bool IsHttpPostRequest(AuthorizationContext filterContext)
    {
    return filterContext.RequestContext.HttpContext.Request.HttpMethod == HttpMethod.Post.ToString();
    }

    private static bool SkipCsrfCheck(AuthorizationContext filterContext)
    {
    return filterContext.ActionDescriptor.GetCustomAttributes(typeof (SkipCSRFCheck), false).Any();
    }
    }

    这使我们能够使用 SkipCSRFCheck 属性逐个禁用它,然后在 Application_Start 中将其注册为全局过滤器:

    GlobalFilters.Filters.Add(new AntiForgeryTokenFilter());

    关于asp.net-mvc - 我将如何编写一个 Action 过滤器来确保每个 Post 操作都使用防伪 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11781191/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com