Asp.net mvc ASP.NET MVC:如何在本地主机上自动禁用[RequireHttps]?
我希望我的登录页面仅为SSL: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证书一起
[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));
});
}
自定义筛选器继承自
设计决策说明:
以上,我会考虑“适当”的解决方案。< /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
}