2010-07-19 97 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