设置 ValidateAntiForgeryToken 属性以在条件下工作

Ben*_*Ben 3 c# asp.net-mvc csrf antiforgerytoken

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

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

    [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
    }
Run Code Online (Sandbox Code Playgroud)

Che*_*iya 5

如果用属性修饰控制器操作方法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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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