dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.43k stars 10.01k forks source link

Using "RequireHttpsAttribute" on a global level in Asp.net 5 #895

Closed Sharpiro closed 9 years ago

Sharpiro commented 9 years ago

I want to declare in code that I want to require the use of HTTPS.

In the past, I used this in Global.asax.cs:

GlobalFilters.Filters.Add(new RequireHttpsAttribute());

I'm currently using this in "ConfigureServices" method of "Startup.cs":

services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
            });

While this works for all of my API calls, it doesn't do anything for my static files and default files which are initialized like so in "Startup.cs":

app.UseDefaultFiles();
app.UseStaticFiles();

I'm currently having to go into Azure after each publish and modify the created web.config (since I don't use it in asp.net 5) and forcing the redirect to HTTPS there.

Is there a way to globally declare the "RequireHttpsAttribute" similar to how it was done in the past? If not, should this be implemented somehow?

Thanks.

davidfowl commented 9 years ago

Filters only apply to MVC, you need to write a piece of middleware that does the same thing as the filter.

guardrex commented 9 years ago

Can't we make changes to a web.config file in our wwwroot folder locally that will stick on publish? I understand it wouldn't be a best practice over creating the middleware to solve this issue, but it might save @Sharpiro some time in the meantime.

davidfowl commented 9 years ago

I don't see how web.config helps

guardrex commented 9 years ago

You can set a rule for IIS to redirect requests for HTTPS that way.

guardrex commented 9 years ago
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
davidfowl commented 9 years ago

Perfect, you don't even need the MVC filter :smile: Just that you; tied to IIS which might be fine for @Sharpiro

Sharpiro commented 9 years ago

The solution @GuardRex posted was actually what i was currently doing. It was just a bit tedious having to paste that code snippet into the azure web.config after every publish from VS. But i actually took @davidfowl 's advice and created some middleware that just forces the redirect.

Thanks.

guardrex commented 9 years ago

@Sharpiro

It was just a bit tedious having to paste that code snippet into the azure web.config after every publish from VS.

What I was trying to say was that you can put that into a web.config file in your project's wwwroot folder and it should merge into web.config for the server. You shouldn't need to keep logging into Azure every publish was my point.

Sharpiro commented 9 years ago

@GuardRex

I see, that is a good idea. However, one of the new features i enjoy about asp.net 5 is the lack of a web.config as needed in my project.

Thanks for your help.

guardrex commented 9 years ago

@Sharpiro Would you be opposed to sharing the middleware bit you created? I'd like to see and possibly use that ... esp for a non-IIS project at some point.

Sharpiro commented 9 years ago

https://github.com/Sharpiro/ASP5_Template/tree/master/src/ASP5_Template_Web/Middleware

Here's a link to the project i've been working on.

I'm pretty new to Owin so it took me a bit to get all the pieces working. But now that it works it looks pretty simple.

This was just a quick implementation so my logic for moving from "http" to "https" is simplistic and only works in a deployed IIS/Azure environment where port number differences do not matter.

guardrex commented 9 years ago

Oh, yes. Indeed. I like that. Very simple ... very effective. I think that will work anywhere. Thanks for sharing. :beer:

davidfowl commented 9 years ago

GetDisplayUrl is the wrong one to use.

Sharpiro commented 9 years ago

@davidfowl

Ok, I changed it to: "context.Request.GetEncodedUrl()"

if that's what you're referring to.

davidfowl commented 9 years ago

Yes, if you read the doc comments:

GetEncodedUrl

Returns the combined components of the request URL in a fully escaped form suitable for use in HTTP headers and other HTTP operations.

GetDisplayUrl

Returns the combined components of the request URL in a fully un-escaped form (except for the QueryString) suitable only for display. This format should not be used in HTTP headers or other HTTP operations.

fletchsod-developer commented 8 years ago

Thanks for sharing.