ASP.NET MVC RequireHttps in Production Only

前端 未结 15 1862
花落未央
花落未央 2020-11-28 18:23

I want to use the RequireHttpsAttribute to prevent unsecured HTTP requests from being sent to an action method.

C#

[RequireHttps] //apply to all acti         


        
15条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-28 18:54

    This won't help if you run Release builds on your development workstation, but conditional compilation could do the job...

    #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()
        {
        }
    
    }
    

    Update

    In Visual Basic, attributes are technically part of the same line as the definition they apply to. You can't put conditional compilation statements inside a line, so you're forced to write the function declaration twice - once with the attribute, and once without. It does work, though, if you don't mind the ugliness.

    #If Not Debug Then
         _
        Function SomeAction() As ActionResult
    #Else
        Function SomeAction() As ActionResult
    #End If
            ...
        End Function
    

    Update 2

    Several people have mentioned deriving from RequireHttpsAttribute without providing an example, so here's one for you. I think that this approach would be much cleaner than the conditional compilation approach, and it would be my preference in your position.

    DISCLAIMER: I haven't tested this code, even a little bit, and my VB is fairly rusty. All I know is that it compiles. I wrote it based on the suggestions of spot, queen3, and Lance Fisher. If it doesn't work, it should at least convey the general idea, and give you starting point.

    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
    

    Basically, the new attribute just quits out instead of running the default SSL authorization code, if the current request is local (that is, you're accessing the site through localhost). You can use it like this:

     _
    Public Class SomeController
    
         _
        Public Function SomeAction() As ActionResult
            ...
        End Function
    
    End Class
    

    Much cleaner! Provided my un-tested code actually works.

提交回复
热议问题