MVC RequireHttps entire site

前端 未结 9 1041
遇见更好的自我
遇见更好的自我 2020-12-23 13:24

I have read the previous posts about using the RequireHttpsAttribute to secure individual controllers:

ASP.NET MVC RequireHttps in Production Only

but is the

相关标签:
9条回答
  • 2020-12-23 13:46

    This isn't using RequireHttps but I think it's a better solution because it catches the redirect sooner in the MVC Lifecycle.

    public class RedirectModule : IHttpModule
    {
        private HttpApplication _context;
    
        public void Init(HttpApplication context)
        {
            _context = context;
            _context.PostResolveRequestCache += HttpRedirect;
        }
    
        public void HttpRedirect(Object src, EventArgs args)
        {
            if (_context.Request.Url.Scheme == Uri.UriSchemeHttp)
            {
                //Redirect to https
                var scheme = Uri.UriSchemeHttps + "://";
                var authority = _context.Request.Url.Authority;
                var url = _context.Request.RawUrl;
    
                var redirectTo = scheme + authority + url;
                _context.Response.PermanentRedirect(redirectTo);
            }
        }
    
        public void Dispose() { }
    }
    

    The idea came from this article.

    You can register the module in your Web.config or inside the Global.asax. I'll show you in the web.cofig.

    <system.webServer>
        <modules>
            <add name="ConfigModuleName" type="Your.Namespace.RedirectModule"/>
        </modules>
    </system.webServer>
    
    0 讨论(0)
  • 2020-12-23 13:48

    You could always add a check at the application level in your global.asax

    protected void Application_BeginRequest(Object sender, EventArgs e)
    {
       if (!HttpContext.Current.Request.IsSecureConnection)
       {
        Response.Redirect("https://" + Request.ServerVariables["HTTP_HOST"]
                                     + HttpContext.Current.Request.RawUrl);
       }
    }
    
    0 讨论(0)
  • 2020-12-23 13:56

    MVC 6 (ASP.NET Core 1.0) works slightly different in it's way of registering filters:

    Startup.cs - AddMvc with filter for RequireHttpsAttribute:

    public void ConfigureServices(IServiceCollection services)
    {
        // TODO: Register other services
    
        services.AddMvc(options =>
        {
            options.Filters.Add(typeof(RequireHttpsAttribute));
        });
    }
    

    Design decisions explained:

    1. Use filter in Startup.cs for global setup (since we want this to apply everywhere). Startup should be responsible for registering and setting up all global rules. If your company employ a new developer, she would expect to find global setup in Startup.cs.
    2. Use RequireHttpsAttribute logic since it's proven (by Microsoft). Never use "magical" strings like "http://" and "https://" when it can be avoided by reusing a Microsoft component created to provide the same logic.

    If you are running your MVC website in localhost without SSL:

    • http://localhost:1337/ (no SSL)
    • https://localhost:1337/ (SSL)

    Consider looking at how to run without SSL in localhost while still requiring https it in production.

    Note:

    As an alternative, we could make a "class BaseController : Controller" and make all our controllers inherit from "BaseController" (instead of Controller). Then we only have to set the attribute 1 global place (and don't need to register filter in Startup.cs).

    Some people prefer the attribute style.

    Example of usage:

    [RequireHttpsAttribute]
    public class BaseController : Controller
    {
        // Maybe you have other shared controller logic..
    }
    
    public class HomeController : BaseController
    {
        // Add endpoints (GET / POST) for Home controller
    }
    
    0 讨论(0)
提交回复
热议问题