【问题标题】:Enforce HTTPS on all pages in MVC application在 MVC 应用程序中的所有页面上强制执行 HTTPS
【发布时间】:2012-10-31 13:30:59
【问题描述】:

我有一个在共享服务器上运行的 ASP.NET MVC3 应用程序。我已经在服务器上安装了 SSL 证书,并且我的应用程序中的所有控制器都装饰有 RequireHTTPS。其目的是确保没有未加密的页面提供(即所有页面都通过 HTTPS 提供)。

但是,某些页面(例如 js、HTML 错误页面)可以在未加密的情况下访问(通过在请求中的主机名中添加 :80)。当然,我正在谈论的页面是静态的,但我如何保护我网站中的所有页面,防止其中任何一个被未经加密下载。我无权访问 IIS 服务器设置,因为这是一个共享站点,但有没有办法使用 HTTP 处理程序或重写 URL 模块(或者我可以直接在文件夹上设置权限)?

感谢您提供任何信息。

【问题讨论】:

  • 页面是什么意思? html 文件?
  • 感谢您的回复,马克。 “页面”是指所有 Html 页面、JS 脚本、图像文件。从那以后,我已经推断出其中大部分的问题(我认为):使用@Url.Content 将它们包括在内,此后它已被直接的“https://...”链接所取代。但是,我使用的是 DevExpress 组件,它们有一个通过“DXR.axd”访问的处理程序,它不使用加密来请求资源(例如 CSS 文件、图像),我不确定是否可以更改。有些东西仍然被不安全地访问,我需要把它找出来或死去。 :)

标签: asp.net-mvc


【解决方案1】:

我使用这样的动作过滤器属性

public class RequireSSL : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase req = filterContext.HttpContext.Request;
        HttpResponseBase res = filterContext.HttpContext.Response;

        //Check if we're secure or not and if we're on the local machine
        if (!req.IsSecureConnection && !req.IsLocal)
        {

            var builder = new UriBuilder(req.Url)

                              {
                                  Scheme = Uri.UriSchemeHttps,
                                  Port = 443
                              };
            res.Redirect(builder.Uri.ToString());
        }
        base.OnActionExecuting(filterContext);

    }


}

然后我用这个属性创建了一个名为 SecureController 的基本控制器

  [RequireSSL]
 public class SecureController : Controller
{

}

那么任何我想成为 SSL 的控制器都会继承这个控制器。 希望有帮助 您只需要确保所有“页面”都是控制器操作返回的视图。如果需要,这应该是一个非常容易的更改。

【讨论】:

  • 谢谢,我不是专家,我想学习;这个 ActionFilter 做了什么 [RequireHttps] 没有做的?无论如何,问题可能出在我请求内容文件的方式上;我使用了@Url.Content,我已经用直接的“https://...”链接替换了我能找到的每个地方。然后我尝试只允许通过 SSL 进行匿名访问,但我仍然被要求授权。所以仍然有一些东西被不安全地访问,我认为这可能与 DevExpress 组件有关,它们有一个通过“DXR.axd”访问的处理程序,它不使用加密并且无法更改 AFAIK。我会继续努力的。再次感谢。
  • 我实际上并不知道 RequireHttps 操作过滤器 :) 它可能在我创建这个过滤器之后就已经发布了。我相信我在 mvc 2 中创建了这个。所以是的,它和我创建的一样。感谢您提供相关信息。
  • 你的意思是我实际上做了一个贡献? :) 我很难相信...无论如何,我需要认真研究 HTTP、HTTPS、端口 80 和 443 等,因为我真的不知道 @Url.Content 是否是问题或是否是其他问题。我的意思是:将 :80 添加到主机名并重新发出请求?再次感谢您的宝贵时间。
最近更新 更多