59

I need to redirect my HTTP site to HTTPS, have added below rule but I am getting 403 Error when tried using http://www.example.com, it works fine when I type https://www.example.com in browser.

<system.webServer>
    <rewrite>
        <rules>
            <rule name="HTTP to HTTPS redirect" stopProcessing="true">
                <match url="(.*)" />
                <conditions>
                    <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                </conditions>
                <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/{R:1}" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>
CuriousSuperhero
  • 6,531
  • 4
  • 27
  • 50
Laxmi Lal Menaria
  • 1,433
  • 4
  • 17
  • 30

11 Answers11

117

You can do it in code:

Global.asax.cs

protected void Application_BeginRequest(){
    if (!Context.Request.IsSecureConnection)
        Response.Redirect(Context.Request.Url.ToString().Replace("http:", "https:"));
}

Or You could add the same code to an action filter:

public class SSLFilter : ActionFilterAttribute {

    public override void OnActionExecuting(ActionExecutingContext filterContext){
        if (!filterContext.HttpContext.Request.IsSecureConnection){
            var url = filterContext.HttpContext.Request.Url.ToString().Replace("http:", "https:");
            filterContext.Result = new RedirectResult(url);
        }
    }
}
Basic
  • 26,321
  • 24
  • 115
  • 201
Chris Kooken
  • 32,730
  • 15
  • 85
  • 123
  • Moving my redirect logic to Application_BeginRequest() resolved an issue I was having where I was trying to do a redirect based on the typed URL. – farina Apr 08 '11 at 18:22
  • The Application_BeginRequest() worked perfectly for me, thanks. – Alex Oct 18 '12 at 09:59
  • 16
    the code is not very correct: the following url `http://example.com?someParam=http:` will be transformed into `https://example.com?someParam=https:` modifying parameters string, consider using `string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;` (taken from RequireHttpsAttribute which also do the exactly same thing) – cloudguy Apr 28 '16 at 12:40
  • 1
    @cloudguy i suggest posting it as an answer – OrElse Apr 29 '16 at 10:45
  • Wow. I am very grateful to this thread. I googled "RequireHttpsAttribute" and ended up coding a solution that would disable redirects on my localhost dev environment but enable a custom class in production. Here is the thread I started: http://stackoverflow.com/questions/37042763/mvc-permanent-way-to-use-redirects-for-http-to-https-and-turn-off-for-dev-enviro – JustJohn May 05 '16 at 05:07
  • 3
    If url's params contains an url or some other `http:` in it, it will be converted too. So I think you should just add the s in the 4th position: `Response.Redirect(Context.Request.Url.ToString().Insert(4, "s"));`. See my answer – Matthieu Charbonnier Dec 21 '16 at 11:00
60

In the Global.asax.cs:

Simple redirect

protected void Application_BeginRequest()
{
    if (!Context.Request.IsSecureConnection
        && !Context.Request.IsLocal // to avoid switching to https when local testing
        )
    {
        // Only insert an "s" to the "http:", and avoid replacing wrongly http: in the url parameters
        Response.Redirect(Context.Request.Url.ToString().Insert(4, "s"));
    }
}

301 redirect: SEO best practice (Search Engine Optimization)

The 301 Moved Permanently redirect status response code is considered a best practice for upgrading users from HTTP to HTTPS (see Google recommendations).

So if Google or Bing robots will be redirected too, consider this:

protected void Application_BeginRequest()
{
    if (!Context.Request.IsSecureConnection
        && !Context.Request.IsLocal // to avoid switching to https when local testing
        )
    {
        Response.Clear();
        Response.Status = "301 Moved Permanently";
        Response.AddHeader("Location", Context.Request.Url.ToString().Insert(4, "s"));
        Response.End();
    }
}
Matthieu Charbonnier
  • 2,794
  • 25
  • 33
15

I use the following in Global.asax:

protected void Application_BeginRequest()
{
  if (FormsAuthentication.RequireSSL && !Request.IsSecureConnection)
  {
    Response.Redirect(Request.Url.AbsoluteUri.Replace("http://", "https://"));
  }
}
Debasis Goswami
  • 174
  • 1
  • 2
  • 3
    It's incomplete, because any `http` in the parameters of the url would be replaced too. [See my answer](https://stackoverflow.com/a/41260494/1280523) – Matthieu Charbonnier Oct 05 '18 at 07:41
7

I have the following ASP.NET MVC rewrite rule in Web.config file:

You can try this code with web.config file. If your URL is http://www.example.com then it will be redirect to this URL https://www.example.com.

<system.webServer>
    <rewrite>
        <rules>
             <rule name="http to https" stopProcessing="true">
              <match url="(.*)" />
              <conditions>
               <add input="{HTTPS}" pattern="^OFF$" />
              </conditions>
              <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>
3

You could use the RequireHttpsAttribute for simple cases.

[RequireHttps]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

As stated in MSDN...

"Represents an attribute that forces an unsecured HTTP request to be re-sent over HTTPS."

RequireHttpsAttribute

I'm not sure you'd want to use this to enforce HTTPS across a large site though. Lots of decorating to do, and opportunity to miss controllers.

Nattrass
  • 1,283
  • 16
  • 27
  • 1
    does not work if you have childactions (renderaction) ;-) – juFo Jan 27 '17 at 13:36
  • Good spot, what does it do in that case? – Nattrass Jan 27 '17 at 13:40
  • 1
    Just crash. "Child actions are not allowed to perform redirect actions. " "Exception Details: System.InvalidOperationException: Child actions are not allowed to perform redirect actions." – juFo Jan 27 '17 at 14:01
3

Use this code in web.config file for redirect http:// to https://

<configuration>
  <system.webServer>
    <rewrite>
        <rules>
            <rule name="HTTPS force" enabled="true" stopProcessing="true">
                <match url="(.*)" />
                <conditions>
                    <add input="{HTTPS}" pattern="^OFF$" />
                </conditions>
                <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
            </rule>
        </rules>
    </rewrite>
   </system.webServer></configuration>
Deepak Jha
  • 359
  • 2
  • 10
3

It's very simple. Just add one line in "Global.asax" file as below:

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

If you would like to apply only server-side, not local side then apply following code:

protected void Application_Start()
{
   if (!HttpContext.Current.Request.IsLocal)
         GlobalFilters.Filters.Add(new RequireHttpsAttribute(true));
}

Hope it will help you :) Thank you!

SadikAli
  • 594
  • 1
  • 4
  • 21
2

I did it thusly, since a local debug session uses custom port numbers:

    protected void Application_BeginRequest()
    {
        if (!Context.Request.IsSecureConnection)
        {
            if (HttpContext.Current.Request.IsLocal)
            {
                Response.Redirect(Context.Request.Url.ToString().Replace("http://localhost:25885/", "https://localhost:44300/"));
            }
            else
            {
                Response.Redirect(Context.Request.Url.ToString().Replace("http://", "https://"));
            }
        }
    }

Preferably there would be some way to get the URL and SSL URL programmatically...

Paul Williams
  • 3,099
  • 38
  • 34
1

To force https only when the website is lunched on the server and ignore it while running the website on your machine for development :

In Global.asax :

You'll need the Application_BeginRequest() method

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
         // .....
    }

    //force https on server, ignore it on local machine
    protected void Application_BeginRequest()
    {
        if (!Context.Request.IsSecureConnection && !Context.Request.Url.ToString().Contains("localhost"))
            Response.Redirect(Context.Request.Url.ToString().Replace("http:", "https:"));
    }
}
Adel Mourad
  • 1,351
  • 16
  • 13
1

This answer is not exactly for OP but for those who could not make it work like me and have come across this (and although I know there is 403 not 404 error in OP), please refer to this answer if you are getting 404 instead: https://stackoverflow.com/a/6962829/5416602

Please check that you have binding for HTTP port (80) and not only HTTPS port (443) in your IIS

Umair Malhi
  • 565
  • 1
  • 5
  • 16
0

I'm unable to add comments, but thought this supplementary info would maybe help somebody.

I implemented the Global.asax idea with the 301 Permanent Redirect, and added http binding to the site in IIS. It still gave me 403 Forbidden until I remembered to untick "Require SSL" in SSL Settings.

cherry
  • 517
  • 5
  • 12