ASP.NET MVC RequireHttps仅适用于生产

Zac*_*son 121 asp.net-mvc ssl https visual-studio

我想使用RequireHttpsAttribute来防止将不安全的HTTP请求发送到操作方法.

C#

[RequireHttps] //apply to all actions in controller
public class SomeController 
{
    [RequireHttps] //apply to this action only
    public ActionResult SomeAction()
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

VB

<RequireHttps()> _
Public Class SomeController

    <RequireHttps()> _
    Public Function SomeAction() As ActionResult
        ...
    End Function

End Class
Run Code Online (Sandbox Code Playgroud)

不幸的是,ASP.NET Development Server不支持HTTPS.

如何在发布到生产环境时使我的ASP.NET MVC应用程序使用RequireHttps,而不是在ASP.NET Development Server上的开发工作站上运行时?

Joe*_*ler 129

如果您在开发工作站上运行Release版本,这将无济于事,但条件编译可以完成这项工作......

#if !DEBUG
[RequireHttps] //apply to all actions in controller
#endif
public class SomeController 
{
    //... or ...
#if !DEBUG
    [RequireHttps] //apply to this action only
#endif
    public ActionResult SomeAction()
    {
    }

}
Run Code Online (Sandbox Code Playgroud)

更新

在Visual Basic中,属性在技术上与它们应用的定义属于同一行.你不能把条件编译语句放在一行中,所以你被迫写两次函数声明 - 一次使用属性,一次不使用.但是,如果你不介意丑陋,它确实有效.

#If Not Debug Then
    <RequireHttps()> _
    Function SomeAction() As ActionResult
#Else
    Function SomeAction() As ActionResult
#End If
        ...
    End Function
Run Code Online (Sandbox Code Playgroud)

更新2

有几个人提到的是RequireHttpsAttribute没有提供一个例子,所以这里有一个给你.我认为这种方法比条件编译方法更清晰,而且我的偏好是你的立场.

免责声明:我没有测试过这段代码,甚至一点点,我的VB相当生疏.我所知道的只是它编译.我是根据spot,queen3和Lance Fisher的建议写的.如果它不起作用,它至少应该传达一般的想法,并给你起点.

Public Class RemoteRequireHttpsAttribute
    Inherits System.Web.Mvc.RequireHttpsAttribute

    Public Overrides Sub OnAuthorization(ByVal filterContext As  _
                                         System.Web.Mvc.AuthorizationContext)
        If IsNothing(filterContext) Then
            Throw New ArgumentNullException("filterContext")
        End If

        If Not IsNothing(filterContext.HttpContext) AndAlso _
            filterContext.HttpContext.Request.IsLocal Then
            Return
        End If

        MyBase.OnAuthorization(filterContext)
    End Sub

End Class
Run Code Online (Sandbox Code Playgroud)

基本上,如果当前请求是本地请求(即,您通过localhost访问该站点),则新属性将退出而不是运行默认SSL授权代码.你可以像这样使用它:

<RemoteRequireHttps()> _
Public Class SomeController

    <RemoteRequireHttps()> _
    Public Function SomeAction() As ActionResult
        ...
    End Function

End Class
Run Code Online (Sandbox Code Playgroud)

更干净!如果我未经测试的代码实际上有效.

  • 谢谢 - 这正是我所需要的.干杯! (2认同)

mik*_*esl 65

如果有人需要C#版本:

using System;
using System.Web.Mvc;

namespace My.Utils
{
    public class MyRequireHttpsAttribute : RequireHttpsAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.HttpContext != null && filterContext.HttpContext.Request.IsLocal)
            {
                return;
            }

            base.OnAuthorization(filterContext);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Lan*_*her 26

从RequireHttps派生是一种很好的方法.

要完全解决问题,您也可以在本地计算机上使用带有自签名证书的IIS.IIS比内置的Web服务器更快,您的优势在于您的开发环境更像是生产环境.

Scott Hanselman在使用VS2010和IIS Express实现本地HTTPS的几种方法方面拥有丰富的资源.

  • +1就是这样.移动部件越少越好 (7认同)

gt1*_*124 12

利用MVC过滤系统和Global.asax.cs,我假设你可以这样做......

    protected void Application_Start()
    {
      RegisterGlobalFilters(GlobalFilters.Filters);
    }

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
      if(Config.IsProduction) //Some flag that you can tell if you are in your production environment.
      {
        filters.Add(new RequireHttpsAttribute());
      }
    }
Run Code Online (Sandbox Code Playgroud)


Sam*_*ack 10

由于ASP.Net开发服务器首先引起了您的问题,因此值得注意的是,微软现在拥有随Visual Studio一起提供的IIS Express(自VS2010 SP1起).这是IIS的简化版本,与开发服务器一样易于使用,但支持IIS 7.5的完整功能集,包括SSL.

Scott Hanselman 在IIS Express中有关于使用SSL的详细帖子.


spo*_*pot 9

如何在自定义属性中继承RequireHttps属性.然后,在自定义属性中,检查当前请求的IsLocal属性,以查看请求是否来自本地计算机.如果是,则不应用基本功能.否则,调用基本操作.