Besides simply redirecting from HTTP to HTTPS, the RequireHttps attribute also changes my URL's question mark ?
to %3F
. Unsurprisingly, that breaks things.
Why? How do I fix it?
scenario:
I try to navigate to
http://www.example.com/message/compose
But let's say I don't have permission to view 开发者_如何学Pythonthat page.
<HandleError()> _ Public Class MessageController Inherits System.Web.Mvc.Controller Function Compose() As ActionResult ... If ... Then Throw New Exception(Net.HttpStatusCode.Unauthorized.ToString) End If ... Return View() End Function ... End Class
The action throws an exception.
The exception is handled by my Error.aspx page
<%@ Page Language="VB" Inherits="System.Web.Mvc.ViewPage(Of System.Web.Mvc.HandleErrorInfo)" %> <script runat="server"> Sub Page_Load(ByVal Sender As System.Object, ByVal e As System.EventArgs) If Model.Exception.Message = Net.HttpStatusCode.Unauthorized.ToString Then response.redirect("/signin?ReturnUrl=" + Url.Encode(request.Path)) End If ... End Sub </script> ...
I'm redirected to my Sign In page at
http://www.example.com/signin?ReturnUrl=%2fmessage%2fcompose
But I'm using HTTP and not HTTPS. My action requires HTTPS. (That RemoteRequireHttps inherits from RequireHttps and overrides its OnAuthorization method to simply disregard localhost.)
<HandleError()> _ Public Class AccountController Inherits System.Web.Mvc.Controller <RemoteRequireHttps()> _ Function SignIn() As ActionResult ... End Function ... End Class
I'm redirected to
https://www.example.com/signin%3FReturnUrl=%2fmessage%2fcompose
I see this error in my browser:
Bad Request
It seems that RequireHttps changes my question mark ?
to %3F
.
We're considering using a URL rewriter like ISAPI Rewrite to handle things like this before they ever get to your code. Of course, this would only work if you have access to the server.
Also, if you're using IIS 7, I believe it comes with URL rewriting functionality built in.
My answer to my own question here might help (appears to be a bug in MVC 2 Preview 2)
Can I ask why you're not using [Authorize] or a custom authorization attribute. If you're using .NET authentication you should use [Authorize].
Note: even if you do use [Authorize] it doesnt actually fix the problem you're experiencing.
I've just reengineered this to avoid the question mark (and also exception throws) altogether.
scenario:
I try to navigate to http://www.example.com/message/compose
But let's say I don't have permission to view that page.
Public Class MessageController
Inherits System.Web.Mvc.Controller
Function Compose() As ActionResult
...
If ... Then
Return RedirectToAction("SignIn", "Account", New With {.ReturnUrl = Request.Path})
End If
...
Return View()
End Function
...
End Class
I'm redirected to my Sign In page. My route looks like this:
routes.MapRoute( _
"SignIn", _
"signin/{*ReturnUrl}", _
New With {.controller = "Account", _
.action = "SignIn", _
.ReturnUrl = ""} _
)
So that's at address http://www.example.com/signin/message/compose
But I'm using HTTP and not HTTPS. My action requires HTTPS.
Public Class AccountController
Inherits System.Web.Mvc.Controller
<RemoteRequireHttps()> _
Function SignIn(ByVal ReturnUrl As String) As ActionResult
...
End Function
...
End Class
I'm redirected to https://www.example.com/signin/message/compose
No question mark. No problem.
精彩评论