So situation sketch:
I've created a website in asp.net core, i've got it up and running. A couple of days ago my hosting provider added the option to configure SSL so I did that leaving me with the problem that there was no redirection from http to https. I've started looking on the web for solutions and figured out some code that works in 3 of the 4 cases on the hosting and 4 of the 4 cases when tested locally on IIS.
So what works:
- https://www.someurl.com -> no redirection needed
- https://someurl.com -> redirects to https://www.someurl.com
- http://someurl.com -> redirects to https://www.someurl.com
- http://www.someurl.com -> gives a redirect error:ERR_TOO_MANY_REDIRECTS
The following code was used in the asp.net core 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 in the web.config to cover that one case where asp.net redirection not works 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" tot this line:
The result still is err too many redirection but then with http://someurl.com/iworkiworkiworkiworkiworkiworkiworkiworkiworkiwork as resulting url.
So I'm at a loss for what exactly is going wrong and out of ideas on how to fix it, any ideas?