要解决此问题,您需要发现
您的过滤器被多次调用(假设是!),我发现了一种发生这种情况的方式,但对您来说可能不同(在过滤器的第一行附加一个调试器,并查看调用堆栈,以查看是什么触发了它)。
HomeController
ContentSecurityPolicyFilterAttribute
过滤器只执行一次:
public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.HttpContext.Response;
response.AddHeader("Content-Security-Policy", "default-src *; img-src * data:; ");
base.OnActionExecuting(filterContext);
}
}
filters.Add(new ContentSecurityPolicyFilterAttribute());
使用上面的代码,我只看到
Content-Security-Policy
Index
中的操作
更改为:
return RedirectToAction("Contact");
指数
/Home/Contact
并且两者仅包含一个CSP头。
内容安全策略
Partial Views
.
如果您使用的是部分视图,那么这很可能是重复头的原因,特别是当它们调用控制器动作来填充自己时。
public ActionResult PartialContentForHome()
{
return View("PartialContentForHome");
}
在“视图\共享”下创建新的局部视图称为
PartialContentForHome.cshtml
@{
Layout = null;
}
<h1>
Partial!
</h1>
最后,添加
@Html.Action("PartialContentForHome", "Home")
进入视图文件
Views\Home\Index.cshtml
-
获取由两者组成的页面
视图\主页\索引。cshtml
Views\Shared\PartialContentForHome.cshtml
-
将达到CSP过滤器第一行上设置的断点
两次
-
将在发送到客户端的响应中看到CSP头的两个实例
如果问题是由部分视图/调用控制器操作引起的,则需要确保过滤器将自身调节为每个请求仅执行一次。一种方法是在
HttpContext.Items
集合用作“我已经添加了标题”标记,例如:
public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.RequestContext.HttpContext.Items.Contains(nameof(ContentSecurityPolicyFilterAttribute)))
{
HttpResponseBase response = filterContext.HttpContext.Response;
response.AddHeader("Content-Security-Policy", "default-src *; img-src * data:; ");
filterContext.RequestContext.HttpContext.Items.Add(nameof(ContentSecurityPolicyFilterAttribute), string.Empty);
}
base.OnActionExecuting(filterContext);
}
}
HttpContext。项目
HttpContext。项目
因此,如果它再次运行
全体的
案例,以确保过滤器不会在每个请求中执行多次,但我们可以为标头执行一次更好的过滤器,具体来说:
public class ContentSecurityPolicyFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpResponseBase response = filterContext.HttpContext.Response;
var header = response.Headers["Content-Security-Policy"];
if (header == null)
{
response.AddHeader("Content-Security-Policy", "default-src *; img-src * data:; ");
}
base.OnActionExecuting(filterContext);
}
}
i、 e.我们需要做的就是检查头是否在响应的
Headers
集合,如果是,则不要再次添加。