[c#] How to force HTTPS using a web.config file

I have searched around Google and StackOverflow trying to find a solution to this, but they all seem to relate to ASP.NET etc.

I usually run Linux on my servers but for this one client I am using Windows with IIS 7.5 (and Plesk 10). This being the reason why I am slightly unfamiliar with IIS and web.config files. In an .htaccess file you can use rewrite conditions to detect whether the protocol is HTTPS and redirect accordingly. Is there a simple way to achieve this using a web.config file, or even using the 'URL Rewrite' module that I have installed?

I have no experience with ASP.NET so if this is involved in the solution then please include clear steps of how to implement.

The reason for me doing this with the web.config and not PHP is that I would like to force HTTPS on all assets within the site.

This question is related to c# asp.net iis https web-config

The answer is


The accepted answer did not work for me. I followed the steps on this blog.

A key point that was missing for me was that I needed to download and install the URL Rewrite Tool for IIS. I found it here. The result was the following.

<rewrite>
        <rules>
            <remove name="Http to Https" />
            <rule name="Http to Https" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
                <match url="*" />
                <conditions>
                    <add input="{HTTPS}" pattern="off" />
                </conditions>
                <serverVariables />
                <action type="Redirect" url="https://{HTTPS_HOST}{REQUEST_URI}" />
            </rule>
        </rules>
    </rewrite>

For those using ASP.NET MVC. You can use the RequireHttpsAttribute to force all responses to be HTTPS:

GlobalFilters.Filters.Add(new RequireHttpsAttribute());

Other things you may also want to do to help secure your site:

  1. Force Anti-Forgery tokens to use SSL/TLS:

    AntiForgeryConfig.RequireSsl = true;
    
  2. Require Cookies to require HTTPS by default by changing the Web.config file:

    <system.web>
        <httpCookies httpOnlyCookies="true" requireSSL="true" />
    </system.web>
    
  3. Use the NWebSec.Owin NuGet package and add the following line of code to enable Strict Transport Security (HSTS) across the site. Don't forget to add the Preload directive below and submit your site to the HSTS Preload site. More information here and here. Note that if you are not using OWIN, there is a Web.config method you can read up on on the NWebSec site.

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHsts(options => options.MaxAge(days: 720).Preload());
    
  4. Use the NWebSec.Owin NuGet package and add the following line of code to enable Public Key Pinning (HPKP) across the site. More information here and here.

    // app is your OWIN IAppBuilder app in Startup.cs
    app.UseHpkp(options => options
        .Sha256Pins(
            "Base64 encoded SHA-256 hash of your first certificate e.g. cUPcTAZWKaASuYWhhneDttWpY3oBAkE3h2+soZS7sWs=",
            "Base64 encoded SHA-256 hash of your second backup certificate e.g. M8HztCzM3elUxkcjR2S5P4hhyBNf6lHkmjAHKhpGPWE=")
        .MaxAge(days: 30));
    
  5. Include the https scheme in any URL's used. Content Security Policy (CSP) HTTP header and Subresource Integrity (SRI) do not play nice when you imit the scheme in some browsers. It is better to be explicit about HTTPS. e.g.

    <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.4/bootstrap.min.js">
    </script>
    
  6. Use the ASP.NET MVC Boilerplate Visual Studio project template to generate a project with all of this and much more built in. You can also view the code on GitHub.


In .Net Core, follow the instructions at https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl

In your startup.cs add the following:

// Requires using Microsoft.AspNetCore.Mvc;
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(options =>
    {
        options.Filters.Add(new RequireHttpsAttribute());
    });`enter code here`

To redirect Http to Https, add the following in the startup.cs

// Requires using Microsoft.AspNetCore.Rewrite;
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    var options = new RewriteOptions()
       .AddRedirectToHttps();

    app.UseRewriter(options);

To augment LazyOne's answer, here is an annotated version of the answer.

<rewrite>
  <rules>
     <clear />
     <rule name="Redirect all requests to https" stopProcessing="true">
       <match url="(.*)" />
         <conditions logicalGrouping="MatchAll">
           <add input="{HTTPS}" pattern="off" ignoreCase="true" />
         </conditions>
         <action 
            type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" 
            redirectType="Permanent" appendQueryString="false" />
     </rule>
  </rules>
</rewrite>

Clear all the other rules that might already been defined on this server. Create a new rule, that we will name "Redirect all requests to https". After processing this rule, do not process any more rules! Match all incoming URLs. Then check whether all of these other conditions are true: HTTPS is turned OFF. Well, that's only one condition (but make sure it's true). If it is, send a 301 Permanent redirect back to the client at http://www.foobar.com/whatever?else=the#url-contains. Don't add the query string at the end of that, because it would duplicate the query string!

This is what the properties, attributes, and some of the values mean.

  • clear removes all server rules that we might otherwise inherit.
  • rule defines a rule.
    • name an arbitrary (though unique) name for the rule.
    • stopProcessing whether to forward the request immediately to the IIS request pipeline or first to process additional rules.
  • match when to run this rule.
    • url a pattern against which to evaluate the URL
  • conditions additional conditions about when to run this rule; conditions are processed only if there is first a match.
    • logicalGrouping whether all the conditions must be true (MatchAll) or any of the conditions must be true (MatchAny); similar to AND vs OR.
  • add adds a condition that must be met.
    • input the input that a condition is evaluating; input can be server variables.
    • pattern the standard against which to evaluate the input.
    • ignoreCase whether capitalization matters or not.
  • action what to do if the match and its conditions are all true.
    • type can generally be redirect (client-side) or rewrite (server-side).
    • url what to produce as a result of this rule; in this case, concatenate https:// with two server variables.
    • redirectType what HTTP redirect to use; this one is a 301 Permanent.
    • appendQueryString whether to add the query string at the end of the resultant url or not; in this case, we are setting it to false, because the {REQUEST_URI} already includes it.

The server variables are

  • {HTTPS} which is either OFF or ON.
  • {HTTP_HOST} is www.mysite.com, and
  • {REQUEST_URI} includes the rest of the URI, e.g. /home?key=value
    • the browser handles the #fragment (see comment from LazyOne).

See also: https://www.iis.net/learn/extensions/url-rewrite-module/url-rewrite-module-configuration-reference


A simple way is to tell IIS to send your custom error file for HTTP requests. The file can then contain a meta redirect, a JavaScript redirect and instructions with link, etc... Importantly, you can still check "Require SSL" for the site (or folder) and this will work.

</configuration>
</system.webServer>
    <httpErrors>
        <clear/>
        <!--redirect if connected without SSL-->
        <error statusCode="403" subStatusCode="4" path="errors\403.4_requiressl.html" responseMode="File"/>
    </httpErrors>
</system.webServer>
</configuration>

I am using below code and it perfect works for me, hope it will help you.

<configuration>
<system.webServer>
    <rewrite>
        <rules>
            <rule name="Force redirect to https" stopProcessing="true">
                <match url="(.*)" />
                <conditions>
                    <add input="{HTTPS}" pattern="^OFF$" />
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" appendQueryString="false" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

I was not allowed to install URL Rewrite in my environment, so, I found another path.

Adding this to my web.config added the error rewrite and worked on IIS 7.5:

<system.webServer>
    <httpErrors errorMode="Custom" defaultResponseMode="File" defaultPath="C:\WebSites\yoursite\" >    
    <remove statusCode="403" subStatusCode="4" />
    <error statusCode="403" subStatusCode="4" responseMode="File" path="redirectToHttps.html" />
</httpErrors>

Then, following the advice here: https://www.sslshopper.com/iis7-redirect-http-to-https.html

I configured the IIS website to require SSL and created the html file that does the redirect (redirectToHttps.html) upon the 403 (Forbidden) error:

<html>
<head><title>Redirecting...</title></head>
<script language="JavaScript">
function redirectHttpToHttps()
{
    var httpURL= window.location.hostname + window.location.pathname + window.location.search;
    var httpsURL= "https://" + httpURL;
    window.location = httpsURL;
}
redirectHttpToHttps();
</script>
<body>
</body>
</html>

I hope someone finds this useful as I could not find all of the pieces in one place anywhere else.


The excellent NWebsec library can upgrade your requests from HTTP to HTTPS using its upgrade-insecure-requests tag within the Web.config:

<nwebsec>
  <httpHeaderSecurityModule>
    <securityHttpHeaders>
      <content-Security-Policy enabled="true">
        <upgrade-insecure-requests enabled="true"  />
      </content-Security-Policy>
    </securityHttpHeaders>
  </httpHeaderSecurityModule>
</nwebsec>

Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to iis

ASP.NET Core 1.0 on IIS error 502.5 CS1617: Invalid option ‘6’ for /langversion; must be ISO-1, ISO-2, 3, 4, 5 or Default Publish to IIS, setting Environment Variable IIS Manager in Windows 10 The page cannot be displayed because an internal server error has occurred on server The service cannot accept control messages at this time NuGet: 'X' already has a dependency defined for 'Y' Changing project port number in Visual Studio 2013 System.Data.SqlClient.SqlException: Login failed for user "This operation requires IIS integrated pipeline mode."

Examples related to https

What's the net::ERR_HTTP2_PROTOCOL_ERROR about? Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website Android 8: Cleartext HTTP traffic not permitted ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" How do I make a https post in Node Js without any third party module? Page loaded over HTTPS but requested an insecure XMLHttpRequest endpoint How to force Laravel Project to use HTTPS for all routes? Could not create SSL/TLS secure channel, despite setting ServerCertificateValidationCallback Use .htaccess to redirect HTTP to HTTPs

Examples related to web-config

No assembly found containing an OwinStartupAttribute Error IIS Config Error - This configuration section cannot be used at this path How to enable GZIP compression in IIS 7.5 how to set start page in webconfig file in asp.net c# Authentication issue when debugging in VS2013 - iis express Forms authentication timeout vs sessionState timeout Specified argument was out of the range of valid values. Parameter name: site Access-control-allow-origin with multiple domains "An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page..." ASP.NET: HTTP Error 500.19 – Internal Server Error 0x8007000d