URL redirect error

So, a sketch of the situation:

I created a website in asp.net core, I have it. A couple of days ago, my hosting provider added an option to set up SSL, so I did it, leaving the issue of not redirecting from http to https. I started looking online for solutions and figured out a code that works 3 out of 4 cases on hosting and 4 out of 4 cases when tested locally in IIS.

So what works:

The following code was used in the base asp.net site:

public void Configure(...) {
  app.UseHttpsWorldWideWebRedirect();
}

public static class HttpsWorldWideWebRedirectMiddlewareExtensions
    {
        public static IApplicationBuilder UseHttpsWorldWideWebRedirect(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<HttpsWorldWideWebRedirectMiddleware>();
        }
    }

public class HttpsWorldWideWebRedirectMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<HttpsWorldWideWebRedirectMiddleware> _logger;

    public HttpsWorldWideWebRedirectMiddleware(RequestDelegate next, ILogger<HttpsWorldWideWebRedirectMiddleware> logger)
    {
        _next = next;
        _logger = logger;
        _logger.LogInformation("Https WWW redirect module loaded");
    }

    public async Task Invoke(HttpContext context)
    {
        var protoHeader = context.Request.Headers["X-Forwarded-Proto"].ToString();
        var ignoreHttps = false;
        var ignoreWww = false;

        if (context.Request.IsHttps || protoHeader.ToLower().Equals("https"))

        {
            ignoreHttps = true;
        }

        if (context.Request.Host.Host.StartsWith("www", StringComparison.OrdinalIgnoreCase) || string.Equals(context.Request.Host.Host, "localhost", StringComparison.OrdinalIgnoreCase))
        {
            ignoreWww = true;
        }

        if (ignoreWww && ignoreHttps)
        {
            await _next.Invoke(context);
        }
        else
        {
            var www = ignoreWww ? "" : "www.";
            var newPath =
                $"https://{www}{context.Request.Host.Value}{context.Request.PathBase}{context.Request.Path}{context.Request.QueryString}";
            _logger.LogDebug($"'{context.Request.GetDisplayUrl()}' was rewritten into '{newPath}'");
            context.Response.Headers["X-Forwarded-Proto"] = "https";
            context.Response.Redirect(newPath, true);
        }
    }
}

      

The next step I tried was adding a redirect to the web.config to cover the case where the asp.net redirect doesn't work using the following code:

<rewrite>
  <rules>
    <rule name="Redirect to https if http://www" stopProcessing="true">
      <match url="(.*)" />
      <conditions logicalGrouping="MatchAny">
        <add input="{HTTP_HOST}" pattern="^www.*"/>
        <add input="{HTTPS}" pattern="Off" />
      </conditions>
      <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
    </rule>
  </rules>
</rewrite>

      

As a test, I added "iwork" to this line:  

The result still triggers too many redirects, but then http://someurl.com/iworkiworkiworkiworkiworkiworkiworkiworkiworkiwork as the result url.

So I am at a loss what exactly is going wrong and from ideas on how to fix it, any ideas?

+3


source to share


3 answers


Don't know anything about .NET Core, but it can certainly be done with url rewriting rules.

You need at least 2 rewrite rules.

  • Redirect HTTP requests to https with www.
  • Redirect request to https without www. prefix https with www.


This will reduce the redirect chain as much as possible.


<rewrite>
    <rules>
        <rule name="Redirect all http requests to https with www" stopProcessing="true">
            <match url=".*" />
            <conditions trackAllCaptures="true">
                <add input="{HTTP_HOST}" pattern="^localhost" negate="true" />
                <add input="{HTTPS}" pattern="off" />
                <add input="{HTTP_HOST}" pattern="^(?:www\.)?(.+)$" />
            </conditions>
            <action type="Redirect" url="https://www.{C:1}/{R:0}" />
        </rule>
        <rule name="Redirect https requests with no www prefix to https with www" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^localhost" negate="true" />
                <add input="{HTTPS}" pattern="on" />
                <add input="{HTTP_HOST}" pattern="^www\." negate="true" />
            </conditions>
            <action type="Redirect" url="https://www.{HTTP_HOST}/{R:0}" />
        </rule>
    </rules>
</rewrite>

      

+4


source


There is existing middleware that automatically handles the redirect to HTTPS. Just add the following to the top of your Configure () method in your Startup class:

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

      



If you are using the API, you can also add the RequireHttpsAttribute filter to your MVC options in ConfigureServices ():

services.AddMvc(mvcOptions => 
        {
            mvcOptions.Filters.Add(new RequireHttpsAttribute());

        });

      

+2


source


We just ran into something very similar in our Azure configuration, and in the end the best way was to use the rewrite module in web.config and not try to handle it in code.

This is very close to what we added to our server, it should work for you with a few minor changes:

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Add WWW">
        <match url="^(.*)$" />
        <conditions>
          <add input="{HTTP_HOST}" pattern="^(?!www\.)(.*)$" />
        </conditions>
        <action type="Redirect" url="www.{C:0}{PATH_INFO}" redirectType="Permanent" />
       </rule>
      <rule name="Redirect to HTTPS">
        <match url="(.*)" />
        <conditions>
          <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          <add input="{URL}" pattern="/$" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        </conditions>
        <action type="Redirect" url="https://{SERVER_NAME}/{R:1}" redirectType="SeeOther" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

      

Here are two sites that have useful information:

https://docs.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-the-url-rewrite-module

http://blog.smarx.com/posts/redirecting-to-https-in-windows-azure-two-methods

+1


source







All Articles