2010-07-19 53 views
52

我已阅读有关使用RequireHttpsAttribute,以确保各个控制器以前的职位:MVC RequireHttps整个网站

ASP.NET MVC RequireHttps in Production Only

,但有没有将其应用到整个网站的方法吗?由于我的主机(discountasp.net),我无法使用“RequireSSL IIS”设置。

+0

我会推荐一个自定义重定向模块,因为它会在mvc生命周期中更快地捕获并重定向。我会做这个不同于这篇文章[http://alexwolfthoughts.com/efficient-mvc-redirects-using-an-http-module],但它显示了一些可能性。 – christo8989 2016-03-29 22:26:42

回答

20

我结束了使用IIS URL重写2.0,迫使该网站切换到HTTPS在应用层添加一个检查。这个代码在web.config中有诀窍:

<system.webServer> 
    <!-- This uses URL Rewrite 2.0 to force the entire site into SSL mode --> 
    <rewrite xdt:Transform="Insert"> 
     <rules> 
     <rule name="Force HTTPS" enabled="true"> 
      <match url="(.*)" ignoreCase="false" /> 
      <conditions> 
      <add input="{HTTPS}" pattern="off" /> 
      </conditions> 
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" /> 
     </rule> 
     </rules> 
    </rewrite> 
    </system.webServer> 
+0

对于任何发现这些年后来和我一样,这在vs2017中给我造成了一个错误。下面的答案类似于此工作:https://stackoverflow.com/a/47095/4180481 – Ozan 2017-11-03 12:48:19

-2

您可以为所有控制器使用基类,并使用require ssl属性对其进行修饰。

+4

我(或其他团队成员)不想意外忘记将属性添加到新的控制器,或者忘记从基类继承。我们希望它是万无一失的。 – CodeGrue 2010-07-19 21:02:12

+0

@CodeGrue:你总是可以添加一个单元测试,声明所有的控制器都使用这个属性;看到我最近关于可序列化属性的问题:http://stackoverflow.com/questions/3257004/how-to-determine-if-all-objects-are-serializable-in-a-given-namespace – DanP 2010-07-19 21:05:23

18

你总是可以在您的Global.asax

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    if (!HttpContext.Current.Request.IsSecureConnection) 
    { 
    Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"] 
           + HttpContext.Current.Request.RawUrl); 
    } 
} 
95

RequireHttpsAttribute注册为全局过滤器。

在Global.asax中:

protected void Application_Start() 
{ 
    GlobalFilters.Filters.Add(new RequireHttpsAttribute()); 

    //... other stuff 
} 
+0

绝对是最干净的方法。 – 2014-01-20 17:54:22

+0

我正在这样做,我得到一个重定向循环。 URL重写为我工作。 – 2014-02-21 04:52:47

+4

@RacielR。我以前遇到过同样的问题,问题是托管合作伙伴在防火墙接受了ssl,但是通过http发送请求到我的服务器......确保您的主机伙伴不是这样做的。 – Julian 2014-03-05 09:41:05

11

只是把这个答案高达日期为MVC 3及以上使用您Filterconfig.cs文件下面的App_start文件夹内

 filters.Add(new RequireHttpsAttribute()); 

显然你需要你的服务器IIS配置为使用有效的SSL证书,可以在这里购买便宜的证书:https://www.namecheap.com/我认为我最后一次购买一个,每个域名每年9美元。

+0

欣赏你花时间回来并更新这个问题与最新的答案 – 2015-05-15 20:46:07

+0

是RequireHttpsAttribute预期重定向用户到HTTPS时,用户输入HTTP,或将它抛出一个403错误,而不是? – usefulBee 2016-01-14 17:44:28

+0

有趣的是,RequireHttpsAttribute发送302(临时)重定向不是301.奇怪,因为301是一个永久重定向,看起来更适用于此处。无论如何,重要的是要记住,这只是通过HTTP第一次通过HTTP调用网站,将302推送到HTTPS,然后该会话中的所有后续呼叫都在HTTPS协议中。有办法克服302,1在这里通过建议Ben的方式http://benjii.me/2015/10/redirect-to-https-asp-net-mvc/ – 2016-01-15 05:55:25

3

这不是使用RequireHttps,但我认为这是一个更好的解决方案,因为它在MVC Lifecycle中更早地捕获重定向。

public class RedirectModule : IHttpModule 
{ 
    private HttpApplication _context; 

    public void Init(HttpApplication context) 
    { 
     _context = context; 
     _context.PostResolveRequestCache += HttpRedirect; 
    } 

    public void HttpRedirect(Object src, EventArgs args) 
    { 
     if (_context.Request.Url.Scheme == Uri.UriSchemeHttp) 
     { 
      //Redirect to https 
      var scheme = Uri.UriSchemeHttps + "://"; 
      var authority = _context.Request.Url.Authority; 
      var url = _context.Request.RawUrl; 

      var redirectTo = scheme + authority + url; 
      _context.Response.PermanentRedirect(redirectTo); 
     } 
    } 

    public void Dispose() { } 
} 

想法来自这个article

您可以在Web.configGlobal.asax的内部注册该模块。我会在web.cofig中向你展示。

<system.webServer> 
    <modules> 
     <add name="ConfigModuleName" type="Your.Namespace.RedirectModule"/> 
    </modules> 
</system.webServer> 
+0

我认为'PermanentRedirect'应该是'RedirectPermanent' – 2016-11-05 00:04:43

+0

Application_BeginRequest似乎在PostResolveRequestCache中注册的事件处理程序之前被调用了。 – odyth 2017-07-11 22:08:41

0

在Global.asax.cs中,使用“RegisterGlobalFilters”注册全局属性。

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    filters.Add(new RequireHttpsAttribute()); 
    //e.g. filters.Add(new HandleErrorAttribute()); 
    //e.g. filters.Add(new System.Web.Mvc.AuthorizeAttribute());    
} 
3

MVC 6(ASP.NET 1.0的核心)的作品略有不同,在它的注册过滤器的方式:

Startup.cs - AddMvc与过滤器RequireHttpsAttribute

public void ConfigureServices(IServiceCollection services) 
{ 
    // TODO: Register other services 

    services.AddMvc(options => 
    { 
     options.Filters.Add(typeof(RequireHttpsAttribute)); 
    }); 
} 

设计决策解释:

  1. 在Startup.cs中使用过滤器对于全局设置(因为我们希望它适用于任何地方)。启动应负责注册和设置所有全球规则。如果您的公司雇用了一名新开发人员,她希望能够在Startup.cs中找到全局设置。
  2. 使用RequireHttpsAttribute逻辑,因为它已被证明(由微软)。切勿使用“http://”和“https://”之类的“魔术”字符串,以避免重复使用创建的Microsoft组件来提供相同的逻辑。

如果您正在运行在本地主机你的MVC网站没有SSL:

  • HTTP://本地主机:1337 /(无SSL)
  • HTTPS://本地主机:1337 /(SSL)

考虑看how to run without SSL in localhost while still requiring https it in production

注:

作为替代,我们可以做一个“类BaseController:控制器”,使我们的所有控制器的(而不是控制器)“BaseController”继承。然后我们只需要设置属性1的全局位置(并且不需要在Startup.cs中注册过滤器)。

有些人更喜欢属性风格。用法

例子:

[RequireHttpsAttribute] 
public class BaseController : Controller 
{ 
    // Maybe you have other shared controller logic.. 
} 

public class HomeController : BaseController 
{ 
    // Add endpoints (GET/POST) for Home controller 
} 
4

在你FilterConfig.cs应用此:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
{ 
    // only if Debug is not enabled, do not require https for local development 
    if (!HttpContext.Current.IsDebuggingEnabled) 
      filters.Add(new RequireHttpsAttribute()); 

    //... any other filters 
} 

这应该强迫你的应用程序来使用https每一页上。

+0

尚未见到'IsDebuggingEnabled'! – madannes 2017-12-03 20:07:28