Skip to content
This repository has been archived by the owner on Dec 18, 2018. It is now read-only.

Redirect HTTP to HTTPS using ASP.NET Core RC2 #916

Closed
DavidDury opened this issue Jun 6, 2016 · 23 comments
Closed

Redirect HTTP to HTTPS using ASP.NET Core RC2 #916

DavidDury opened this issue Jun 6, 2016 · 23 comments

Comments

@DavidDury
Copy link

DavidDury commented Jun 6, 2016

In RC1 I created a Service Middleware that did the redirection trick

Service:

public class HttpsRedirectService
   {
    private readonly RequestDelegate _next;

    public HttpsRedirectService(RequestDelegate next)
    {
        _next = next;
    }
    public async Task Invoke(HttpContext context)
    {

        if (context.Request.IsHttps)
        {
            await _next.Invoke(context);
        }
        else
        {    
            context.Response.Redirect(string.Format("https://{0}{1}", context.Request.Host.ToString(), context.Request.Path.ToString()), true);
        }
    }
}

The extension:

public static IApplicationBuilder UseHttpsRedirectService(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<HttpsRedirectService>();
    }

and then in Startup.cs

    app.UseHttpsRedirectService();

The problem is now it ends up in a redirect loop no matter if I use HTTP or HTTPS.

Any ideas how can I make this work so that if the user goes to http://localhost, he will be redirected to https://localhost or real domain.

@DavidDury DavidDury changed the title Redirect HTTP to HTTPS Redirect HTTP to HTTPS ASP.NET Core RC2 Jun 6, 2016
@DavidDury DavidDury changed the title Redirect HTTP to HTTPS ASP.NET Core RC2 Redirect HTTP to HTTPS using ASP.NET Core RC2 Jun 6, 2016
@davidfowl
Copy link
Member

Are you running behind IIS? aspnet/IISIntegration#140

@DavidDury
Copy link
Author

DavidDury commented Jun 6, 2016

@davidfowl : Azure Web Site. I read the referenced link but that issue is for a filter right? The reason why I use a service middleware is because it will run quite early in the pipeline before the request has hit the controller.

@ealsur
Copy link

ealsur commented Jun 6, 2016

+1
I'm using a rudimentary:

app.Use(async (httpContext, next) =>
   {
    var url = httpContext.Request.GetDisplayUrl();
    if (!url.StartsWith("https"))
    {
           httpContext.Response.Redirect("https://www.mydomain.com" + (httpContext.Request.Path.HasValue ? httpContext.Request.Path.Value : string.Empty), true);
           return;
       }
       await next();
   });

And runs ok locally, but on Azure I get an ERR_TOO_MANY_REDIRECTS :(

@benaadams
Copy link
Contributor

benaadams commented Jun 6, 2016

IIS and Kestrel will be communicating via http on localhost so you will keep redirecting as IIS is doing https offload. (Edit: ANCM should handle this anyway, see reply #916 (comment))

Instead add this to your web.config to have the redirect happen at the IIS level:

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="HTTP/S to HTTPS Redirect" enabled="true" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAny">
              <add input="{SERVER_PORT_SECURE}" pattern="^0$" />
            </conditions>
            <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

@Tratcher
Copy link
Member

Tratcher commented Jun 6, 2016

Yeah, https isn't being correctly forwarded in Azure web sites right now. Here's a workaround:
aspnet/IISIntegration#140 (comment)

FYI @DavidDury: your redirect logic is dropping some parts of the url. It should be more like:
context.Response.Redirect(string.Format("https://{0}{1}{2}{3}", context.Request.Host, context.Request.PathBase, context.Request.Path, context.Request.QueryString), true);

@ealsur
Copy link

ealsur commented Jun 6, 2016

@benaadams The problem with web.config is that it applies even when we run on development. Web.config transformations are not working. How can I turn the rewrite off locally? Or make the transformations work?

@guardrex
Copy link

guardrex commented Jun 6, 2016

@ealsur You could try this from @nil4 https://github.com/nil4/dotnet-transform-xdt

@ealsur
Copy link

ealsur commented Jun 6, 2016

Thanks @guardrex , my project uses WindowsAzure.Storage package, which supports .NetStandard 1.5 but dotnet-transform-xdt supports .NetCoreApp 1.0, I'll try to sort that out and see if that project helps.

@guardrex
Copy link

guardrex commented Jun 6, 2016

There shouldn't be any connection or problem there.

@nil4
Copy link

nil4 commented Jun 6, 2016

@ealsur I wrote dotnet-transform-xdt based on dotnet-publish-iis (which also targets netcoreapp1.0). If you encounter any problems, please file an issue and I will try to look into it.

I updated the readme to reflect that dotnet transform-xdt should come before dotnet publish-iis.

@ealsur
Copy link

ealsur commented Jun 6, 2016

Thanks @guardrex & @nil4 !
I managed to get it working on netcoreapp 1.0 with no issues :)

@moozzyk
Copy link
Contributor

moozzyk commented Jun 6, 2016

@nil4, @ealsur - tools should target netcoreapp1.0. dotnet never runs tools using desktop CLR

@nil4 - it would be interesting to understand why the placeholders are not replaced if you run your xdt after publish-iis. I would think that either the Xml structure is not what publish-iis assumes or xdt uses the version in the project.json as source and overwrites the target web.config that publish-iis already fixed at the target location.

@nil4
Copy link

nil4 commented Jun 7, 2016

@moozzyk spot on, thanks! In my example, xdt uses the Web.config file from the project folder as input, not the one in the publish output folder. The placeholders being still present is thus expected.

@muratg muratg added this to the 1.0.1 milestone Jun 9, 2016
@JohnGalt1717
Copy link

+1 on web.config not working in dev. VS.net just hanges if this is in the web.config in development. This should just work. (and did in RC1)

@guardrex
Copy link

There is a difference between Debug and Release folders, where debugging locally is running out of Debug and publishing is out of Release, at least insofar as VS Code is concerned. I haven't gone back to VS yet.

If IIS Express is using the Debug build to run the app, does IIS Express respect a web.config in the Debug folder that is different than the one you might have in the Release > publish folder?

I wonder if the copyToOutput > include could be a path to a different web.config than the publishOptions > include web.config -- or would this not be the case and not work for some reason?

@muratg muratg modified the milestones: Discussions, 1.1.0 Jun 28, 2016
@imsam67
Copy link

imsam67 commented Jul 23, 2016

I'm having the same problem when I use the code mentioned above to enforce HTTPS. I get "too many redirects" error in my ASP.NET Core 1.0 targeting .NET 4.6.1

Any solutions to this? Shouldn't this be a simple setting in WebApps in Azure portal?

@ealsur
Copy link

ealsur commented Jul 23, 2016

@imsam67 I got it working with the nuget package mentioned by @nil4 , it works like a charm on Azure by doing web.config transforms like on a VS Publish.

@imsam67
Copy link

imsam67 commented Jul 23, 2016

@ealsur Thank you for your response. I want to make sure I understand this correctly. The solution really boils down to using IIS URL Rewrite. The purpose of the dotnet-transform-xdt is to make the necessary modifications to web.config and push it onto Azure WebApp during publish. Am I getting this right?

@ealsur
Copy link

ealsur commented Jul 23, 2016

@imsam67 correct. URL rewrite is on the roadmap. In the meantime, since Azure Web Apps are wrapped around IIS, config transform and IIS URL Rewrite do the trick.

@imsam67
Copy link

imsam67 commented Jul 23, 2016

Thank you. I appreciate your detailed response.

@aligneddev
Copy link

aligneddev commented Jul 26, 2016

Here's what I learned while trying to do the https redirect: https://gooroo.io/GoorooTHINK/Article/16767/Https-Redirect-with-AspNet-Core-RC2-And-Kestrel-on-Windows/22784

@colltoaction
Copy link

Since this issue is still open, let me ask if the preferred way is to use the Rewrite Middleware in Microsoft.AspNetCore.Rewrite now that we have ASP.NET Core 1.1.

(FYI) I've been using a redirect in web.config and it worked just fine.

@Tratcher
Copy link
Member

The web.config option will be more efficient, but it's not portable. The Rewrite middleware is a good portable solution. The MVC attribute is another good option.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests