在MVC 4应用程序中为所有页面添加X-Frame-Options头信息

48

我试图在我的MVC 4应用程序中添加值设置为“DENY”的X-Frame-Options标头。我查看了一下,似乎这是添加到所有页面的最干净的方法。

然而,当我添加这段代码时,它无法构建。在OnResultExecuting的错误中提示:

"找不到合适的方法来覆盖。"

public class XframeOptions : ActionFilterAttribute
{
    public override void OnResultExecuting(
          System.Web.Mvc.ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.AddHeader(
            "X-Frame-Options", "DENY");
    }
}

如果这是最清晰的方法,我该如何解决这个错误?在MVC 4应用程序中是否有更好的处理方法?


这对我有效,但在<system.webServer>中设置属性无效。这不是我第一次发现system.webServer中的设置被忽略。为什么会这样呢? - Gullbyrd
6个回答

147
如果您需要在每个页面上使用它,则不需要自定义HttpModule或ActionFilter。https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options详细介绍了一个更简单的解决方案:
要配置IIS发送X-Frame-Options头,请将以下内容添加到站点的Web.config文件中:
<system.webServer>
  <!-- ... -->

  <httpProtocol>
    <customHeaders>
      <add name="X-Frame-Options" value="SAMEORIGIN" />
    </customHeaders>
  </httpProtocol>

  <!-- ... -->
</system.webServer>

这是一个更合适的答案。不需要代码,只需配置。 - Alao
1
你好,我刚刚将代码添加到了我的web.config源文件中。但是在运行程序后,我在Chrome测试工具中看不到X-Frame-Options。我错过了什么吗? - user754952
你在这样做之后重新启动了IIS/IIS Express吗?理论上来说,这并不是必需的,因为当你更改web.config时,IIS往往会自动重启。但是我之前曾经因为过于假设而遭受损失。 - robrich
为了有效地防止框架攻击,应用程序应该返回一个名为X-Frame-Options的响应头,并将值设置为DENY以完全防止框架,或者将值设置为SAMEORIGIN以仅允许由响应本身相同源的页面进行框架。请注意,如果应用程序本身可以使不受信任的网站被框架,则SAMEORIGIN标头可以部分绕过。 - nmit026
大多数现代Web浏览器都支持X-Frame-Options HTTP头。确保在您的网站返回的所有网页上设置它(如果您希望页面仅由您服务器上的页面框架包含(例如,它是FRAMESET的一部分),那么您将想要使用SAMEORIGIN,否则,如果您从不希望页面被框架,您应该使用DENY。ALLOW-FROM允许特定网站在支持的Web浏览器中框架网页)。另请参见:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options - nmit026

14

确保你从正确的类继承:

public class XframeOptions : System.Web.Mvc.ActionFilterAttribute

在ASP.NET MVC 4中,有一个名为Web API的不同命名空间,由于您没有明确指定命名空间,我猜编译器选择了错误的类:
System.Web.Http.Filters.ActionFilterAttribute

6
有另一种方法可以实现。创建一个自定义的HttpModule,如下所示:
    public class XframeOptionsModule : IHttpModule
{
    public void Dispose()
    {

    }

    public void Init(HttpApplication context)
    {
        context.PreSendRequestHeaders += this.OnPreSendRequestHeaders;
    }
    private void OnPreSendRequestHeaders(object sender, EventArgs e)
    {
        HttpContext.Current.Response.AddHeader("x-frame-options", "Deny");
    }
}

然后在web.config文件中注册该模块。

    <modules >
        <add name ="XframeOptions" type="your module's full type info"/>
    </modules>

4
您遇到这个错误是因为您使用了错误的方法名称,应该使用OnResultExecuted而不是OnResultExecuting。您应该像这样编写您的方法:
public class XframeOptionsFilter : System.Web.Mvc.ActionFilterAttribute
{
    public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AddHeader("x-frame-options", "Deny");
    }
}

1

但是标准的.Net 允许您通过web.config设置此类安全头,对吧? - Liam

0
要在所有MVC应用程序中添加拒绝“x-frame-options”标题,您可以执行以下操作以避免点击劫持攻击。
using System;
using System.Web;

namespace Demo.Website.Modules
{
    public class XfoHeaderModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += ContextPreSendRequestHeaders;
        }

        public void Dispose()
        {
        }

        private void ContextPreSendRequestHeaders(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Add("X-Frame-Options", "Deny");
        }
    }
}

将以下内容添加到web.config文件中。
  <system.webServer>
    <modules>
      <add name="XfoHeader" type="Demo.Website.Modules.XfoHeaderModule" />
    </modules>
  </system.webServer>

enter image description here


2
最好远离PreSendRequestHeaders事件,因为它已被弃用。请参见:http://www.asp.net/aspnet/overview/web-development-best-practices/what-not-to-do-in-aspnet,-and-what-to-do-instead#presend - klings
2
你的屏幕截图中的响应有2个X-Frame-Options头。这是无效的。 - Liam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接