<p>About 6 months ago I rolled out a site where every request needed to be over https.  The only way at the time I could find to ensure that every request to a page was over https was to check it in the page load event.  If the request was not over http I would response.redirect("<a href="https://example.com" rel="noreferrer">https://example.com</a>")</p>

<p>Is there a better way -- ideally some setting in the web.config?</p>

[{'answer_id': 47095, 'author': 'John Boker', 'author_id': 2847, 'author_profile': 'https://Stackoverflow.com/users/2847', 'pm_score': 9, 'selected': True, 'text': '<p>Please use <a href="https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" rel="noreferrer">HSTS</a> (HTTP Strict Transport Security)</p>\n\n<p>from <a href="http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx" rel="noreferrer">http://www.hanselman.com/blog/HowToEnableHTTPStrictTransportSecurityHSTSInIIS7.aspx</a></p>\n\n<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;\n&lt;configuration&gt;\n    &lt;system.webServer&gt;\n        &lt;rewrite&gt;\n            &lt;rules&gt;\n                &lt;rule name="HTTP to HTTPS redirect" stopProcessing="true"&gt;\n                    &lt;match url="(.*)" /&gt;\n                    &lt;conditions&gt;\n                        &lt;add input="{HTTPS}" pattern="off" ignoreCase="true" /&gt;\n                    &lt;/conditions&gt;\n                    &lt;action type="Redirect" url="https://{HTTP_HOST}/{R:1}"\n                        redirectType="Permanent" /&gt;\n                &lt;/rule&gt;\n            &lt;/rules&gt;\n            &lt;outboundRules&gt;\n                &lt;rule name="Add Strict-Transport-Security when HTTPS" enabled="true"&gt;\n                    &lt;match serverVariable="RESPONSE_Strict_Transport_Security"\n                        pattern=".*" /&gt;\n                    &lt;conditions&gt;\n                        &lt;add input="{HTTPS}" pattern="on" ignoreCase="true" /&gt;\n                    &lt;/conditions&gt;\n                    &lt;action type="Rewrite" value="max-age=31536000" /&gt;\n                &lt;/rule&gt;\n            &lt;/outboundRules&gt;\n        &lt;/rewrite&gt;\n    &lt;/system.webServer&gt;\n&lt;/configuration&gt;\n</code></pre>\n\n<p><strong>Original Answer</strong> (replaced with the above on 4 December 2015)</p>\n\n<p>basically</p>\n\n<pre><code>protected void Application_BeginRequest(Object sender, EventArgs e)\n{\n   if (HttpContext.Current.Request.IsSecureConnection.Equals(false) &amp;&amp; HttpContext.Current.Request.IsLocal.Equals(false))\n   {\n    Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"]\n+   HttpContext.Current.Request.RawUrl);\n   }\n}\n</code></pre>\n\n<p>that would go in the global.asax.cs (or global.asax.vb)</p>\n\n<p>i dont know of a way to specify it in the web.config</p>\n'}, {'answer_id': 47110, 'author': 'FlySwat', 'author_id': 1965, 'author_profile': 'https://Stackoverflow.com/users/1965', 'pm_score': 4, 'selected': False, 'text': '<p>If you are unable to set this up in IIS for whatever reason, I\'d make an HTTP module that does the redirect for you:</p>\n\n<pre><code>using System;\nusing System.Web;\n\nnamespace HttpsOnly\n{\n    /// &lt;summary&gt;\n    /// Redirects the Request to HTTPS if it comes in on an insecure channel.\n    /// &lt;/summary&gt;\n    public class HttpsOnlyModule : IHttpModule\n    {\n        public void Init(HttpApplication app)\n        {\n            // Note we cannot trust IsSecureConnection when \n            // in a webfarm, because usually only the load balancer \n            // will come in on a secure port the request will be then \n            // internally redirected to local machine on a specified port.\n\n            // Move this to a config file, if your behind a farm, \n            // set this to the local port used internally.\n            int specialPort = 443;\n\n            if (!app.Context.Request.IsSecureConnection \n               || app.Context.Request.Url.Port != specialPort)\n            {\n               app.Context.Response.Redirect("https://" \n                  + app.Context.Request.ServerVariables["HTTP_HOST"] \n                  + app.Context.Request.RawUrl);    \n            }\n        }\n\n        public void Dispose()\n        {\n            // Needed for IHttpModule\n        }\n    }\n}\n</code></pre>\n\n<p>Then just compile it to a DLL, add it as a reference to your project and place this in web.config:</p>\n\n<pre><code> &lt;httpModules&gt;\n      &lt;add name="HttpsOnlyModule" type="HttpsOnly.HttpsOnlyModule, HttpsOnly" /&gt;\n &lt;/httpModules&gt;\n</code></pre>\n'}, {'answer_id': 2269476, 'author': 'Mark', 'author_id': 18264, 'author_profile': 'https://Stackoverflow.com/users/18264', 'pm_score': 7, 'selected': False, 'text': '<p>The IIS7 module will let you redirect.</p>\n\n<pre><code>    &lt;rewrite&gt;\n        &lt;rules&gt;\n            &lt;rule name="Redirect HTTP to HTTPS" stopProcessing="true"&gt;\n                &lt;match url="(.*)"/&gt;\n                &lt;conditions&gt;\n                    &lt;add input="{HTTPS}" pattern="^OFF$"/&gt;\n                &lt;/conditions&gt;\n                &lt;action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther"/&gt;\n            &lt;/rule&gt;\n        &lt;/rules&gt;\n    &lt;/rewrite&gt;\n</code></pre>\n'}, {'answer_id': 4190691, 'author': 'Alexander', 'author_id': 509015, 'author_profile': 'https://Stackoverflow.com/users/509015', 'pm_score': 2, 'selected': False, 'text': '<p>It also depends on the brand of your balancer, for the web mux, you would need to look for http header <code>X-WebMux-SSL-termination: true</code> to figure that incoming traffic was ssl. details here: <a href="http://www.cainetworks.com/support/redirect2ssl.html" rel="nofollow">http://www.cainetworks.com/support/redirect2ssl.html</a></p>\n'}, {'answer_id': 8234498, 'author': 'Troy Hunt', 'author_id': 73948, 'author_profile': 'https://Stackoverflow.com/users/73948', 'pm_score': 7, 'selected': False, 'text': '<p>The other thing you can do is use <a href="http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security" rel="noreferrer">HSTS</a> by returning the "Strict-Transport-Security" header to the browser. The browser has to support this (and at present, it\'s primarily Chrome and Firefox that do), but it means that once set, the browser won\'t make requests to the site over HTTP and will instead translate them to HTTPS requests before issuing them. Try this in combination with a redirect from HTTP:</p>\n\n<pre><code>protected void Application_BeginRequest(Object sender, EventArgs e)\n{\n  switch (Request.Url.Scheme)\n  {\n    case "https":\n      Response.AddHeader("Strict-Transport-Security", "max-age=300");\n      break;\n    case "http":\n      var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;\n      Response.Status = "301 Moved Permanently";\n      Response.AddHeader("Location", path);\n      break;\n  }\n}\n</code></pre>\n\n<p>Browsers that aren\'t HSTS aware will just ignore the header but will still get caught by the switch statement and sent over to HTTPS.</p>\n'}, {'answer_id': 13847410, 'author': 'Paul Schroeder', 'author_id': 1392711, 'author_profile': 'https://Stackoverflow.com/users/1392711', 'pm_score': 2, 'selected': False, 'text': '<p>For @Joe above, "This is giving me a redirect loop. Before I added the code it worked fine. Any suggestions? – Joe Nov 8 \'11 at 4:13"</p>\n\n<p>This was happening to me as well and what I believe was happening is that there was a load balancer terminating the SSL request in front of the Web server.  So, my Web site was always thinking the request was "http", even if the original browser requested it to be "https".</p>\n\n<p>I admit this is a bit hacky, but what worked for me was to implement a "JustRedirected" property that I could leverage to figure out the person was already redirected once.  So, I test for specific conditions that warrant the redirect and, if they are met, I set this property (value stored in session) prior to the redirection.  Even if the http/https conditions for redirection are met the second time, I bypass the redirection logic and reset the "JustRedirected" session value to false.  You\'ll need your own conditional test logic, but here\'s a simple implementation of the property:</p>\n\n<pre><code>    public bool JustRedirected\n    {\n        get\n        {\n            if (Session[RosadaConst.JUSTREDIRECTED] == null)\n                return false;\n\n            return (bool)Session[RosadaConst.JUSTREDIRECTED];\n        }\n        set\n        {\n            Session[RosadaConst.JUSTREDIRECTED] = value;\n        }\n    }\n</code></pre>\n'}, {'answer_id': 23977980, 'author': 'yarg', 'author_id': 2418212, 'author_profile': 'https://Stackoverflow.com/users/2418212', 'pm_score': 2, 'selected': False, 'text': '<p>If SSL support is not configurable in your site (ie. should be able to turn https on/off) - you can use the [RequireHttps] attribute on any controller / controller action you wish to secure.</p>\n'}, {'answer_id': 26232427, 'author': 'Chandan Kumar', 'author_id': 707137, 'author_profile': 'https://Stackoverflow.com/users/707137', 'pm_score': 3, 'selected': False, 'text': '<p>What you need to do is :</p>\n\n<p>1) Add a key inside  of web.config, depending upon the production or stage server like below</p>\n\n<pre><code>&lt;add key="HttpsServer" value="stage"/&gt;\n             or\n&lt;add key="HttpsServer" value="prod"/&gt;\n</code></pre>\n\n<p>2) Inside your Global.asax file add below method.</p>\n\n<pre><code>void Application_BeginRequest(Object sender, EventArgs e)\n{\n    //if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "prod")\n    if (ConfigurationManager.AppSettings["HttpsServer"].ToString() == "stage")\n    {\n        if (!HttpContext.Current.Request.IsSecureConnection)\n        {\n            if (!Request.Url.GetLeftPart(UriPartial.Authority).Contains("www"))\n            {\n                HttpContext.Current.Response.Redirect(\n                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://www."), true);\n            }\n            else\n            {\n                HttpContext.Current.Response.Redirect(\n                    Request.Url.GetLeftPart(UriPartial.Authority).Replace("http://", "https://"), true);\n            }\n        }\n    }\n}\n</code></pre>\n'}, {'answer_id': 29126120, 'author': 'Muhammad Rehan Saeed', 'author_id': 1212017, 'author_profile': 'https://Stackoverflow.com/users/1212017', 'pm_score': 5, 'selected': False, 'text': '<p>For those using ASP.NET MVC. You can use the following to force SSL/TLS over HTTPS over the whole site in two ways:</p>\n\n<p><strong>The Hard Way</strong></p>\n\n<p>1 - Add the RequireHttpsAttribute to the global filters:</p>\n\n<pre><code>GlobalFilters.Filters.Add(new RequireHttpsAttribute());\n</code></pre>\n\n<p>2 - Force Anti-Forgery tokens to use SSL/TLS:</p>\n\n<pre><code>AntiForgeryConfig.RequireSsl = true;\n</code></pre>\n\n<p>3 - Require Cookies to require HTTPS by default by changing the Web.config file:</p>\n\n<pre><code>&lt;system.web&gt;\n    &lt;httpCookies httpOnlyCookies="true" requireSSL="true" /&gt;\n&lt;/system.web&gt;\n</code></pre>\n\n<p>4 - Use the NWebSec.Owin NuGet package and add the following line of code to enable Strict Transport Security accross the site. Don\'t forget to add the Preload directive below and submit your site to the <a href="https://hstspreload.appspot.com" rel="noreferrer">HSTS Preload site</a>. More information <a href="http://rehansaeed.com/nwebsec-asp-net-mvc-security-through-http-headers/" rel="noreferrer">here</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security" rel="noreferrer">here</a>. Note that if you are not using OWIN, there is a Web.config method you can read up on on the <a href="https://github.com/NWebsec" rel="noreferrer">NWebSec</a> site.</p>\n\n<pre><code>// app is your OWIN IAppBuilder app in Startup.cs\napp.UseHsts(options =&gt; options.MaxAge(days: 30).Preload());\n</code></pre>\n\n<p>5 - Use the NWebSec.Owin NuGet package and add the following line of code to enable Public Key Pinning (HPKP) across the site. More information <a href="http://rehansaeed.com/nwebsec-asp-net-mvc-security-through-http-headers/" rel="noreferrer">here</a> and <a href="https://visualstudiogallery.msdn.microsoft.com/6cf50a48-fc1e-4eaf-9e82-0b2a6705ca7d" rel="noreferrer">here</a>.</p>\n\n<pre><code>// app is your OWIN IAppBuilder app in Startup.cs\napp.UseHpkp(options =&gt; options\n    .Sha256Pins(\n        "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",\n        "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")\n    .MaxAge(days: 30));\n</code></pre>\n\n<p>6 - Include the https scheme in any URL\'s used. <a href="http://rehansaeed.com/content-security-policy-for-asp-net-mvc/" rel="noreferrer">Content Security Policy (CSP)</a> HTTP header and <a href="http://rehansaeed.com/subresource-integrity-taghelper-using-asp-net-core/" rel="noreferrer">Subresource Integrity (SRI)</a> do not play nice when you imit the scheme in some browsers. It is better to be explicit about HTTPS. e.g.</p>\n\n<pre><code>&lt;script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js"&gt;&lt;/script&gt;\n</code></pre>\n\n<p><strong>The Easy Way</strong></p>\n\n<p>Use the <a href="https://visualstudiogallery.msdn.microsoft.com/6cf50a48-fc1e-4eaf-9e82-0b2a6705ca7d" rel="noreferrer">ASP.NET MVC Boilerplate</a> Visual Studio project template to generate a project with all of this and much more built in. You can also view the code on <a href="https://github.com/RehanSaeed/ASP.NET-MVC-Boilerplate" rel="noreferrer">GitHub</a>.</p>\n'}, {'answer_id': 33682196, 'author': 'Gup3rSuR4c', 'author_id': 188081, 'author_profile': 'https://Stackoverflow.com/users/188081', 'pm_score': 2, 'selected': False, 'text': "<p>I'm going to throw my two cents in. <strong>IF</strong> you have access to IIS server side, then you can force HTTPS by use of the protocol bindings. For example, you have a website called <em>Blah</em>. In IIS you'd setup two sites: <em>Blah</em>, and <em>Blah (Redirect)</em>. For <em>Blah</em> only configure the <code>HTTPS</code> binding (and <code>FTP</code> if you need to, make sure to force it over a secure connection as well). For <em>Blah (Redirect)</em> only configure the <code>HTTP</code> binding. Lastly, in the <em>HTTP Redirect</em> section for <em>Blah (Redirect)</em> make sure to set a 301 redirect to <code>https://blah.com</code>, with exact destination enabled. Make sure that each site in IIS is pointing to it's <strong>own</strong> root folder otherwise the <em>Web.config</em> will get all screwed up. Also make sure to have <code>HSTS</code> configured on your HTTPSed site so that subsequent requests by the browser are always forced to HTTPS and no redirects occur.</p>\n"}, {'answer_id': 35973181, 'author': 'Santosh K', 'author_id': 5595669, 'author_profile': 'https://Stackoverflow.com/users/5595669', 'pm_score': 1, 'selected': False, 'text': "<p>-> Simply ADD [RequireHttps] on top of the  public class HomeController :        Controller.</p>\n\n<p>-> And add   GlobalFilters.Filters.Add(new RequireHttpsAttribute()); in 'protected void Application_Start()' method in Global.asax.cs file.</p>\n\n<p>Which forces your entire application to HTTPS.</p>\n"}, {'answer_id': 39425833, 'author': 'noelicus', 'author_id': 865643, 'author_profile': 'https://Stackoverflow.com/users/865643', 'pm_score': 2, 'selected': False, 'text': '<p>This is a fuller answer based on @Troy Hunt\'s. Add this function to your <code>WebApplication</code> class in <code>Global.asax.cs</code>:</p>\n\n<pre><code>    protected void Application_BeginRequest(Object sender, EventArgs e)\n    {\n        // Allow https pages in debugging\n        if (Request.IsLocal)\n        {\n            if (Request.Url.Scheme == "http")\n            {\n                int localSslPort = 44362; // Your local IIS port for HTTPS\n\n                var path = "https://" + Request.Url.Host + ":" + localSslPort + Request.Url.PathAndQuery;\n\n                Response.Status = "301 Moved Permanently";\n                Response.AddHeader("Location", path);\n            }\n        }\n        else\n        {\n            switch (Request.Url.Scheme)\n            {\n                case "https":\n                    Response.AddHeader("Strict-Transport-Security", "max-age=31536000");\n                    break;\n                case "http":\n                    var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;\n                    Response.Status = "301 Moved Permanently";\n                    Response.AddHeader("Location", path);\n                    break;\n            }\n        }\n    }\n</code></pre>\n\n<p>(To enable SSL on your local build enable it in the Properties dock for the project)</p>\n'}, {'answer_id': 42969197, 'author': 'user7755300', 'author_id': 7755300, 'author_profile': 'https://Stackoverflow.com/users/7755300', 'pm_score': 1, 'selected': False, 'text': '<p>If you are using ASP.NET Core you could try out the nuget package SaidOut.AspNetCore.HttpsWithStrictTransportSecurity.</p>\n\n<p>Then you only need to add </p>\n\n<pre><code>app.UseHttpsWithHsts(HttpsMode.AllowedRedirectForGet, configureRoutes: routeAction);\n</code></pre>\n\n<p>This will also add HTTP StrictTransportSecurity header to all request made using https scheme.</p>\n\n<p>Example code and documentation <a href="https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code" rel="nofollow noreferrer">https://github.com/saidout/saidout-aspnetcore-httpswithstricttransportsecurity#example-code</a></p>\n'}, {'answer_id': 52229827, 'author': 'Nour Lababidi', 'author_id': 1461144, 'author_profile': 'https://Stackoverflow.com/users/1461144', 'pm_score': 2, 'selected': False, 'text': '<p>I spent sometime looking for best practice that make sense and found the following which worked perfected for me. I hope this will save you sometime. </p>\n\n<p>Using <strong>Config file</strong> (for example an asp.net website)\n<a href="https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/" rel="nofollow noreferrer">https://blogs.msdn.microsoft.com/kaushal/2013/05/22/http-to-https-redirects-on-iis-7-x-and-higher/</a></p>\n\n<p>or on your own server\n<a href="https://www.sslshopper.com/iis7-redirect-http-to-https.html" rel="nofollow noreferrer">https://www.sslshopper.com/iis7-redirect-http-to-https.html</a></p>\n\n<p>[SHORT ANSWER]\nSimply The code below goes inside  </p>\n\n<pre><code>&lt;system.webServer&gt; \n &lt;rewrite&gt;\n     &lt;rules&gt;\n       &lt;rule name="HTTP/S to HTTPS Redirect" enabled="true" \n           stopProcessing="true"&gt;\n       &lt;match url="(.*)" /&gt;\n        &lt;conditions logicalGrouping="MatchAny"&gt;\n        &lt;add input="{SERVER_PORT_SECURE}" pattern="^0$" /&gt;\n       &lt;/conditions&gt;\n       &lt;action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" \n        redirectType="Permanent" /&gt;\n        &lt;/rule&gt;\n       &lt;/rules&gt;\n &lt;/rewrite&gt;\n</code></pre>\n'}, {'answer_id': 53457767, 'author': 'Mike', 'author_id': 914490, 'author_profile': 'https://Stackoverflow.com/users/914490', 'pm_score': 3, 'selected': False, 'text': '<p>In IIS10 (Windows 10 and Server 2016), from version 1709 onwards, there is a new, simpler option for enabling HSTS for a website. </p>\n\n<p>Microsoft describe the advantages of the new approach <a href="https://learn.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/hsts" rel="noreferrer">here</a>, and provide many different examples of how to implement the change programmatically or by directly editing the ApplicationHost.config file (which is like web.config but operates at the IIS level, rather than individual site level). ApplicationHost.config can be found in C:\\Windows\\System32\\inetsrv\\config.</p>\n\n<p>I\'ve outlined two of the example methods here to avoid link rot.</p>\n\n<p><strong>Method 1</strong> - Edit the ApplicationHost.config file directly\nBetween the <code>&lt;site&gt;</code> tags, add this line:</p>\n\n<pre><code>&lt;hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" /&gt;\n</code></pre>\n\n<p><strong>Method 2</strong> - Command Line:\nExecute the following from an elevated command prompt (i.e. right mouse on CMD and run as administrator). Remember to swap Contoso with the name of your site as it appears in IIS Manager.</p>\n\n<pre><code>c:\ncd C:\\WINDOWS\\system32\\inetsrv\\\nappcmd.exe set config -section:system.applicationHost/sites "/[name=\'Contoso\'].hsts.enabled:True" /commit:apphost\nappcmd.exe set config -section:system.applicationHost/sites "/[name=\'Contoso\'].hsts.max-age:31536000" /commit:apphost\nappcmd.exe set config -section:system.applicationHost/sites "/[name=\'Contoso\'].hsts.includeSubDomains:True" /commit:apphost\nappcmd.exe set config -section:system.applicationHost/sites "/[name=\'Contoso\'].hsts.redirectHttpToHttps:True" /commit:apphost\n</code></pre>\n\n<p>The other methods Microsoft offer in that articles might be better options if you are on a hosted environment where you have limited access.</p>\n\n<p>Keep in mind that IIS10 version 1709 is available on Windows 10 now, but for Windows Server 2016 it is on a different release track, and won\'t be released as a patch or service pack.  See <a href="https://learn.microsoft.com/en-us/windows-server/get-started/get-started-with-1709" rel="noreferrer">here</a> for details about 1709.</p>\n'}]
['https://Stackoverflow.com/questions/47089', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4846/']