代码之家  ›  专栏  ›  技术社区  ›  Ben

将ValidateAntiForgeryToken属性设置为在条件下工作

  •  1
  • Ben  · 技术社区  · 7 年前

    我有一个带有POST操作的通用MVC控制器。此控制器用于多个应用程序使用的公共项目中。我们正试图在交错发布过程中添加CSRF保护,通过防伪令牌为每个应用程序一次添加一个CSRF保护。

    如果添加验证属性, [ValidateAntiForgeryToken] 但仅在1个应用程序的视图中包含防伪令牌隐藏表单元素,这将对其他应用程序造成严重破坏。如何基于条件应用此属性。这可能吗?是否需要像下面的代码一样手动执行此操作?有更好的办法吗?

        [HttpPost]
        public ActionResult GenericSection(string nextController, string nextAction, FormCollection form)
        {
            // Validate anti-forgery token if applicable
            if (SessionHandler.CurrentSection.IncludeAntiForgeryToken)
            {
                try
                {
                    AntiForgery.Validate();
                }
                catch (Exception ex)
                {
                    // Log error and throw exception
                }
            }
    
            // If successful continue on and do logic
        }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Chetan    7 年前

    如果将控制器动作方法装饰为 ValidateAntiForgeryToken 属性,则不能通过不在视图中放置隐藏字段来进行转义。

    你需要找出一个方法,你有 属性,在视图中具有令牌的隐藏字段,但仅在需要时验证令牌。

    对于下面的解决方案,我假设您正在讨论的多个应用程序 web.config 文件

    您需要做的是,在中引入一个新的配置 appSettings ,例如 IsAntiForgeryTokenValidationEnabled 或者更简短的名字。

    true 继续验证令牌,否则跳过它。

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class CheckAntiForgeryTokenValidation : FilterAttribute, IAuthorizationFilter
    {
        private readonly IIdentityConfigManager _configManager = CastleClassFactory.Instance.Resolve<IIdentityConfigManager>();
        public void OnAuthorization(AuthorizationContext filterContext)
        {
            var configValue = System.Configuration.ConfigurationManager.AppSettings["IsAntiForgeryTokenValidationEnabled"];
            //Do not validate the token if the config value is not provided or it's value is not "true".
            if(string.IsNullOrEmpty(configValue) || configValue != "true")
            {
                return;
            }
            // Validate the token if the configuration value is "true".
            else
            {
                new ValidateAntiForgeryTokenAttribute().OnAuthorization(filterContext);
            }
        }
    }
    

    OnAuthorization 上述类的方法将在使用此属性的操作方法之前执行,并根据配置值验证或不验证令牌。

    现在,您需要在控制器操作方法上使用此属性,如下例所示。

    public class HomeController : Controller
    {
         [HttpPost]
         [CheckAntiForgeryTokenValidation]
         public ActionResult Save()
         {
             // Code of saving.
         }
    }
    

    在此之后,所有想要验证AntiForgeryToken的应用程序都需要配置 IsAntiForgeryTokenValidationEnabled 在其配置文件中使用值 真的 . 默认情况下,令牌验证不可用,因此如果现有应用程序没有配置,它们仍然可以正常工作,不会出现任何问题。

    我希望这能帮助你解决你的问题。