Aleksa Ristic
Aleksa Ristic

Reputation: 2499

Redirect to https works partially asp net core

I have setup my project to always redirect to https and it works when users type http://website.com or website.com but it doesn't work when he type http://www.website.com or https://www.website.com or www.website.com

This is setup i have:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => false;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddHttpsRedirection(options =>
    {
        options.HttpsPort = 443;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

and inside Configure i do have app.UseHttpsRedirection();

Project is developed in .NET Core 2.1

after some time i came back to this problem since it is not solved yet with any of bellow answers.

Here is full code of my startup - it is messed up since i tried a lot of stuff and to be fair i am lost now...

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Rewrite;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Termodom.Models;

namespace Termodom
{
    public class Startup
    {

        public static string Version = "v1.2.0.0";



        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            Initialize();
        }

        public IConfiguration Configuration { get; }

        private void Initialize()
        {
            AR.AR.ConnectionString = Program.ConnectionString;
            AR.ARWebAuthorization.ARWebAuthorization.AutoUserTimeout = true;
            AR.TDShop.Buffer.Started = true;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            if (true == true) // Do not mind this
            {
                services.AddHsts(ops =>
                {
                    ops.Preload = true;
                    ops.IncludeSubDomains = true;
                });

                services.AddHttpsRedirection(options =>
                {
                    options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
                    options.HttpsPort = 443;
                });
            }

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            AR.Statistic.Visits.Initialize(Path.Combine(env.WebRootPath, "Statistics"));
            AR.Statistic.Visitors.Initialize(Path.Combine(env.WebRootPath, "Statistics"));

            var cultureInfo = new CultureInfo("en-US");
            cultureInfo.NumberFormat.NumberGroupSeparator = ",";
            cultureInfo.NumberFormat.NumberDecimalSeparator = ".";
            cultureInfo.NumberFormat.CurrencyDecimalSeparator = ",";
            cultureInfo.NumberFormat.CurrencyGroupSeparator = ",";
            CultureInfo.DefaultThreadCurrentCulture = cultureInfo;

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
                // app.UseRewriter(new RewriteOptions().AddRedirectToHttps(StatusCodes.Status301MovedPermanently, 443));
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

            app.Run(async (context) =>
            {
                Program.AbsolutePath = env.WebRootPath;
            });
        }
    }
}

Upvotes: 1

Views: 1246

Answers (3)

user9683189
user9683189

Reputation:

TL;DR Your HTTPS middleware is setup properly, but your web app itself might not be listening to www.website.com. Configure your Web server ( IIS ,kestrel, apache or any other ) and (or) the DNS provider to resolve requests from www.website.com, website.com to your web application

Long Story

HttpsRedirection middleware (app.UseHttpsRedirection()) works irrespective of the URL being used to access your application.

i.e. whether you use http://website.com or http://abc.xyz.website.com:2312, the middleware will redirect properly to https://website.com:443 & http://abc.xyz.website.com:443 respectively. ( assuming HttpsPort is set to 443)

Reference : https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpsPolicy/src/HttpsRedirectionMiddleware.cs

        var port = _httpsPort.Value;
        if (port == PortNotFound)
        {
            return _next(context);
        }

        var host = context.Request.Host;
        if (port != 443)
        {
            host = new HostString(host.Host, port);
        }
        else
        {
            host = new HostString(host.Host);
        }

        var request = context.Request;
        var redirectUrl = UriHelper.BuildAbsolute(
            "https", 
            host,
            request.PathBase,
            request.Path,
            request.QueryString);

In Nutshell, what the middleware does, is use the original URL which was used to access your application, and just change the original port to 443 (HttpsPort).

Now as to why you might be facing the issue, your application (or app server) itself might not be listening to requests from http://www.website.com.

If you are using kestrel, you can configure it to listen to all requests on port 80 and 443.

"Kestrel": {
    "EndPoints": {
      "Http": {
        "Url": "http://0.0.0.0:80"
      },
      "Https": {
        "Url": "https://0.0.0.0:443"
      }
    }
  },

If you are testing on your local machine, then you have to add individual entries to the hosts file for all the subdomains your application is listening to (www in your case).
(Hosts file is located at /etc/hosts in linux & C:\Windows\System32\drivers\etc\hosts in windows)
e.g.

#various other entries.
127.0.0.1 www.website.com
127.0.0.1 website.com

In a production environment, you will have to configure the DNS provider to resolve both www.website.com && website.com to the IP address where your app is hosted.

Some other useful links
How to set up subdomains on IIS 7
https://superuser.com/questions/449392/multiple-subdomains-pointing-to-one-website-in-iis

Upvotes: 0

Prabhanath
Prabhanath

Reputation: 108

Just to add at Laz Ziya point the following code snippet should work , have used the same in one of my projects. Hope you have used HttpsRedirection() method properly Check this out and the ports can be mentionted in appsettings.json


Blockquote

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Upvotes: 0

LazZiya
LazZiya

Reputation: 5719

Add HstsOption to include subdomains:

services.AddHsts(ops =>
{
    ops.IncludeSubDomains = true;
});

I assume you already have app.UseHttpsRedirection(); in startup, right?

Reference:

Upvotes: 2

Related Questions