Last active
November 24, 2020 23:22
-
-
Save mattwhetton/72d1cd532115e103600b6b6cfd5c50dc to your computer and use it in GitHub Desktop.
Simple OWIN middleware for doing an HTTPs redirect for all requests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ref: http://www.codenutz.com/https-redirect-asp-net-core-using-owin-middleware/ | |
using System.Threading.Tasks; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.AspNetCore.Builder; | |
namespace SomeNamespace | |
{ | |
public class HttpsRedirectMiddleware { | |
private RequestDelegate _next; | |
public HttpsRedirectMiddleware(RequestDelegate next) { | |
_next = next; | |
} | |
public async Task Invoke(HttpContext context){ | |
var protoHeader = context.Request.Headers["X-Forwarded-Proto"].ToString(); | |
if(context.Request.IsHttps || protoHeader.ToLower().Equals("https")) | |
await _next.Invoke(context); | |
} | |
else | |
{ | |
context.Response.Redirect($"https://{context.Request.Host}{context.Request.Path}"); | |
} | |
} | |
} | |
public static class HttpsRedirectMiddlewareExtensions | |
{ | |
public static IApplicationBuilder UseHttpsRedirect(this IApplicationBuilder builder) | |
{ | |
return builder.UseMiddleware<HttpsRedirectMiddleware>(); | |
} | |
} | |
} |
With a little change works like a charm. Thank you!
The code for OWIN is look like this:
public async override Task Invoke(IOwinContext context)
{
var protoHeader = context.Request.Headers["X-Forwarded-Proto"]?.ToString();
if (context.Request.IsSecure || (protoHeader != null && protoHeader.ToLower().Equals("https")))
{
await Next.Invoke(context);
}
else
{
context.Response.StatusCode = 302;
context.Response.Redirect($"https://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}");
}
}
context.Response.Redirect($"https://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}");
did not work for me beause I use non standard http/https (10080/10043) ports and my webapp listens on a different base path "/app"
- context.Request.Host already includes the port (localhost:10080)
- context.Request.Path did not include the basepath (only /path) for http://localhost:10080/app/path
so the best thing is to se context.Request.Uri for redirection.
- StatusCode 302 is deprecated (has been replaced by 303 but still works in most browsers) but 307 might be a better choice for post requests, since 302/303 perform a GET redirect. Usually not a big issue for browsers but an api might start the communication with a post request.
this is my modified version that works pretty well
public enum RedirectStatusCode
{
Permanent = 301,
SeeOther = 303,
Temporary = 307,
}
public class HttpsRedirectMiddleware : OwinMiddleware
{
private readonly int httpsPort;
private readonly RedirectStatusCode statusCode;
public HttpsRedirectMiddleware(OwinMiddleware next, int httpsPort, RedirectStatusCode statusCode) : base(next)
{
this.httpsPort = httpsPort;
this.statusCode = statusCode;
}
public override async Task Invoke(IOwinContext context)
{
var protoHeader = context.Request.Headers["X-Forwarded-Proto"]?.ToString();
if (context.Request.IsSecure || (protoHeader != null && protoHeader.ToLower().Equals("https")))
{
await Next.Invoke(context);
}
else
{
context.Response.StatusCode = (int)statusCode;
var location = httpsPort == 443
? $"https://{context.Request.Uri.Host}{context.Request.Uri.PathAndQuery}"
: $"https://{context.Request.Uri.Host}:{httpsPort}{context.Request.Uri.PathAndQuery}";
context.Response.Redirect(location);
}
}
}
public static class HttpsRedirectMiddlewareExtensions
{
public static IAppBuilder UseHttpsRedirect(this IAppBuilder builder, int httpsPort = 443, RedirectStatusCode statusCode = RedirectStatusCode.SeeOther)
{
return builder.Use<HttpsRedirectMiddleware>(httpsPort, statusCode);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This isn't OWIN, it's ASP.NET Core.