Asp.net mvc ASP.NET MVC:如何在本地主机上自动禁用[RequireHttps]?

Asp.net mvc ASP.NET MVC:如何在本地主机上自动禁用[RequireHttps]?,asp.net-mvc,debugging,iis,ssl,localhost,Asp.net Mvc,Debugging,Iis,Ssl,Localhost,我希望我的登录页面仅为SSL: [RequireHttps] public ActionResult Login() { if (Helper.LoggedIn) { Response.Redirect("/account/stats"); } return View(); } 但显然,当我开发和调试我的应用程序时,它在本地主机上不起作用。我不想将IIS 7与SSL证书一起

我希望我的登录页面仅为SSL:

    [RequireHttps]
    public ActionResult Login()
    {
        if (Helper.LoggedIn)
        {
            Response.Redirect("/account/stats");
        }

        return View();
    }
但显然,当我开发和调试我的应用程序时,它在本地主机上不起作用。我不想将IIS 7与SSL证书一起使用,如何自动禁用RequireHttps属性

更新

根据StackOverflow用户提供的信息和ASP.NETMVC2源代码,我创建了以下类来解决这个问题

public class RequireSSLAttribute : FilterAttribute, IAuthorizationFilter
{
    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        if (!filterContext.HttpContext.Request.IsSecureConnection)
        {
            HandleNonHttpsRequest(filterContext);
        }
    }

    protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.Url.Host.Contains("localhost")) return;

        if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
        {
            throw new InvalidOperationException("The requested resource can only be accessed via SSL");
        }

        string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
        filterContext.Result = new RedirectResult(url);
    }
}
它是这样使用的:

[RequireSSL]
public ActionResult Login()
{
    if (Helper.LoggedIn)
    {
        Response.Redirect("/account/stats");
    }

    return View();
}

最简单的方法是从RequireHttps派生一个新属性并重写HandleNonHttpsRequest

protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
        {
            if (!filterContext.HttpContext.Request.Url.Host.Contains("localhost"))
            {
                base.HandleNonHttpsRequest(filterContext);
            }
        }

HandleNonHttpsRequest是引发异常的方法,在这里,如果主机是localhost,我们所做的只是不调用它(正如Jeff在他的评论中所说的,您可以将其扩展到测试环境或您想要的任何其他异常)。

您可以将此需求封装在派生属性中:

class RequireHttpsNonDebugAttribute : RequireHttpsAttribute {
    public override void HandleNonHttpsRequest(AuthorizationContext ctx) {
        #if (!DEBUG)
        base.HandleNonHttpsRequest(ctx);
        #endif
    }
}
MVC 6(ASP.NET Core 1.0):

正确的解决方案是使用env.IsProduction()或env.IsDevelopment()

例如:

Startup.cs-使用自定义筛选器添加MVC:

public void ConfigureServices(IServiceCollection services)
{
    // TODO: Register other services

    services.AddMvc(options =>
    {
        options.Filters.Add(typeof(RequireHttpsInProductionAttribute));
    });
}
自定义筛选器继承自

设计决策说明:

  • 使用环境IsProduction()或IsDevelopment(),例如。 “#如果调试”。有时,我们在测试服务器上以调试模式发布/发布,不想禁用此安全要求。这只需要在localhost/development中禁用(因为我们懒得在iisexpress或本地使用的任何东西中设置localhost SSL)
  • 使用Startup.cs中的过滤器进行全局设置(因为我们希望这适用于所有地方)。Startup应负责注册和设置所有全局规则。如果您的公司雇佣了一名新的开发人员,她会希望在Startup.cs中找到全局设置
  • 使用逻辑,因为它已经(由Microsoft)验证过了。我们唯一想改变的是何时应用逻辑(生产),何时不应用逻辑(开发/localhost)。如果可以通过重用为提供相同逻辑而创建的Microsoft组件来避免使用诸如“http://”和“https://”之类的“神奇”字符串,则千万不要使用这些字符串
  • 以上,我会考虑“适当”的解决方案。< /P> 注意:

    作为
    备选方案
    ,我们可以创建一个“类BaseController:Controller”,并使所有控制器从“BaseController”(而不是控制器)继承。然后我们只需要设置属性1全局位置(并且不需要在Startup.cs中注册过滤器)

    有些人更喜欢属性样式。请注意,这将消除设计决策2的好处

    用法示例:

    [RequireHttpsInProductionAttribute]
    public class BaseController : Controller
    {
        // Maybe you have other shared controller logic..
    }
    
    public class HomeController : BaseController
    {
        // Add endpoints (GET / POST) for Home controller
    }
    

    如果您在堆栈溢出中搜索“RequireHttps”,这个问题已经被问了好几次了,所以有很多关于解决方案的信息。这是一个很好的问题,但我还没有使用这个属性,但我可以马上看出这是一个问题。你是对的。这个问题已经解决了,我用帮助我的类更新了我的主要帖子。这个方法可以修改为在测试环境中也不需要HTTPS。我用你的代码和MVC的源代码创建了一个解决方案。谢谢好的,在阅读时,作为一种安全措施,我们应该添加
    filters.add(newrequireslattribute())
    FilterConfig
    ?@stom中,问题特别是关于如何禁用localhost的属性,但是如果我们谈论的是保护整个应用程序的安全,那么您应该将其添加到全局过滤器中,您可能也应该设置
    HTTP严格传输安全性
    头。您可以使用filterContext.HttpContext.Request.IsLocal,而不是搜索字符串。我也考虑过这一点。但这意味着我必须为每个RequireHttps属性添加#if DEBUG。啊,我想这只是一次。其他建议比这更好。添加一些关于代码放置位置的信息会更有帮助,只是为了帮助那些对ASP.NET MVC更不熟悉的人。在我当前的MVC项目中,在App_Start文件夹中有一个名为FilterConfig.cs的默认文件。把它加在那里。
    public void ConfigureServices(IServiceCollection services)
    {
        // TODO: Register other services
    
        services.AddMvc(options =>
        {
            options.Filters.Add(typeof(RequireHttpsInProductionAttribute));
        });
    }
    
    public class RequireHttpsInProductionAttribute : RequireHttpsAttribute
    {
        private bool IsProduction { get; }
    
        public RequireHttpsInProductionAttribute(IHostingEnvironment environment)
        {
            if (environment == null)
                throw new ArgumentNullException(nameof(environment));
            this.IsProduction = environment.IsProduction(); 
        }
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (this.IsProduction)
                base.OnAuthorization(filterContext);
        }
        protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
        {
            if(this.IsProduction)
                base.HandleNonHttpsRequest(filterContext);
        }
    }
    
    [RequireHttpsInProductionAttribute]
    public class BaseController : Controller
    {
        // Maybe you have other shared controller logic..
    }
    
    public class HomeController : BaseController
    {
        // Add endpoints (GET / POST) for Home controller
    }