【问题标题】:Set ValidateAntiForgeryToken Attribute to work on a condition将 ValidateAntiForgeryToken 属性设置为在某个条件下工作
【发布时间】:2018-11-30 00:24:27
【问题描述】:

我有一个带有 POST 操作的通用 MVC 控制器。该控制器用于多个应用程序使用的通用项目中。我们正在尝试在交错发布过程中添加 CSRF 保护,我们通过 Anti Forgery Token 为每个应用程序一次添加一个 CSRF 保护。

如果我将验证属性 [ValidateAntiForgeryToken] 添加到此控制器,但仅在其中 1 个应用程序的视图中包含 Anti Forgery Token 隐藏表单元素,这将对其他应用程序造成严重破坏。如何根据条件应用此属性。这可能吗?这是否需要手动完成,类似于下面的代码?有没有更好的办法?

    [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
    }

【问题讨论】:

  • 你可以做的是,根据一些配置跳过防伪令牌的验证。您共享的代码是否获得了预期的行为?
  • @ChetanRanpariya 是的,上面的代码产生了正确的结果,但是,我希望有更好的方法仍然可以使用注释,从而从控制器方法中删除大量内容。

标签: c# asp.net-mvc csrf antiforgerytoken


【解决方案1】:

如果你用ValidateAntiForgeryToken属性装饰控制器动作方法,你不能通过不把隐藏字段放在视图中来逃避。

您需要找出一种方法,您拥有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方法将在使用该属性的action方法之前执行,并根据配置值验证或不验证token。

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

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

在此之后,所有想要验证 AntiForgeryToken 的应用程序都需要在其配置文件中具有配置 IsAntiForgeryTokenValidationEnabled,其值为 true。令牌验证默认不可用,因此如果现有应用程序没有配置,它们仍然可以正常工作。

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

【讨论】:

  • 这很完美。正是我想要的。更优雅的方法。
猜你喜欢
  • 1970-01-01
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多