ASP.NET MVC:如何在 localhost 上自动禁用 [RequireHttps]?
Posted
技术标签:
【中文标题】ASP.NET MVC:如何在 localhost 上自动禁用 [RequireHttps]?【英文标题】:ASP.NET MVC: How to automatically disable [RequireHttps] on localhost? 【发布时间】:2011-04-07 09:22:11 【问题描述】:我希望我的登录页面仅是 SSL:
[RequireHttps]
public ActionResult Login()
if (Helper.LoggedIn)
Response.Redirect("/account/stats");
return View();
但是当我开发和调试我的应用程序时,显然它在 localhost 上不起作用。我不想使用带有 SSL 证书的 IIS 7,如何自动禁用 RequireHttps 属性?
更新
根据 *** 用户和 ASP.NET MVC 2 源代码提供的信息,我创建了以下解决问题的类。
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();
【问题讨论】:
如果你在 Stack Overflow 上搜索“RequireHttps”,这个问题已经被问了好几次了,所以有很多关于解决方案的信息。这是一个很好的问题,但是我还没有使用过该属性,但我可以立即看到它是一个问题。 你是对的。问题已经解决,我用对我有帮助的课程更新了我的主要帖子。 【参考方案1】:最简单的方法是从 RequireHttps 派生一个新属性并覆盖 HandleNonHttpsRequest
protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
if (!filterContext.HttpContext.Request.Url.Host.Contains("localhost"))
base.HandleNonHttpsRequest(filterContext);
HandleNonHttpsRequest 是引发异常的方法,如果主机是 localhost,我们在这里所做的只是不调用它(正如 Jeff 在他的评论中所说,您可以将其扩展到测试环境或实际上任何其他您想要的异常)。
【讨论】:
此方法可以修改为在测试环境中也不需要 HTTPS。 我使用您的代码和 MVC 的源代码创建了一个解决方案。谢谢! 在阅读this 和this 作为安全措施时,我们应该在FilterConfig
中添加filters.Add(new RequireSSLAttribute ());
吗?
@stom 问题特别是关于如何禁用 localhost 的属性,但如果我们谈论保护您的应用程序作为一个整体,是的,您应该将它添加到您的全局过滤器中,您应该设置 @ 987654326@ 也是标头。
您可以使用 filterContext.HttpContext.Request.IsLocal 而不是搜索字符串【参考方案2】:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
if (!HttpContext.Current.IsDebuggingEnabled)
filters.Add(new RequireHttpsAttribute());
【讨论】:
添加一些关于该代码放置位置的信息会更有帮助,以帮助那些不熟悉 ASP.NET MVC 的人。 在我当前的 MVC 项目中,App_Start 文件夹中有一个名为 FilterConfig.cs 的默认文件。在那里添加它。【参考方案3】:#if (!DEBUG)
[RequireHttps]
#endif
public ActionResult Login()
if (Helper.LoggedIn)
Response.Redirect("/account/stats");
return View();
【讨论】:
我也想过这个。但这意味着我必须为每个 RequireHttps 属性添加#if DEBUG。 啊,我以为只有一次。那么其他的建议更好。【参考方案4】:您可以将此要求封装在派生属性中:
class RequireHttpsNonDebugAttribute : RequireHttpsAttribute
public override void HandleNonHttpsRequest(AuthorizationContext ctx)
#if (!DEBUG)
base.HandleNonHttpsRequest(ctx);
#endif
【讨论】:
【参考方案5】:MVC 6(ASP.NET Core 1.0):
正确的解决方案是使用 env.IsProduction() 或 env.IsDevelopment()。
例子:
Startup.cs - 带有自定义过滤器的 AddMvc:
public void ConfigureServices(IServiceCollection services)
// TODO: Register other services
services.AddMvc(options =>
options.Filters.Add(typeof(RequireHttpsInProductionAttribute));
);
自定义过滤器继承自RequireHttpsAttribute
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);
解释设计决策:
-
使用环境 IsProduction() 或 IsDevelopment(),例如
“#如果调试”。有时我们在测试服务器上以 DEBUG 模式发布/发布,并且不想禁用此安全要求。这只需要在 localhost/development 中禁用(因为我们懒得在 IIS Express 或我们在本地使用的任何东西中设置 localhost SSL)。
在 Startup.cs 中使用过滤器进行全局设置(因为我们希望它适用于任何地方)。 Startup 应负责注册和设置所有全局规则。如果您的公司雇用了一位新开发人员,她会希望在 Startup.cs 中找到全局设置。
使用 RequireHttpsAttribute 逻辑,因为它已被证明(由 Microsoft)。我们唯一要改变的是何时应用逻辑(生产)和何时不应用逻辑(开发/本地主机)。切勿使用“http://”和“https://”之类的“神奇”字符串,因为可以通过重复使用为提供相同逻辑而创建的 Microsoft 组件来避免这种情况。
以上我会考虑“适当”的解决方案。
注意:
作为替代方法,我们可以创建一个“类 BaseController : Controller”,并让我们所有的控制器都继承自“BaseController”(而不是 Controller)。那么我们只需要设置属性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
【讨论】:
以上是关于ASP.NET MVC:如何在 localhost 上自动禁用 [RequireHttps]?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 asp.net mvc 3 项目中路由 .aspx 页面?
如何在 ASP.Net MVC - 5 应用程序中显示版本号并自动递增