views:

94

answers:

2

When trying to apply [RequireHttps] to AccountController.Logon in ASP.NET MVC 2 Preview 2 I get the following error :

ASP.NET detected invalid characters in the URL.

This is because ASP.NET has rewritten my request from

http://example.com/admin to

https://example.com/account/logon%3FReturnUrl=/admin

It is ASP.NET itself that has added ReturnURL (not ASP.NET MVC), but it is the RequireHttps attribute that is redirecting and messing up the URL.

The %3F instead of ? is breaking the page.

I think its technically a bug in ASP.NET. Is there a workaround? I'm thinking maybe a way to handle the 'unauthenticated' event in global.asax - or possibly just fixing the source for RequireHttpsAttribute.

    [RequireHttps]
    public ActionResult LogOn()
    {
        return View(DefaultModel);
    }

    <authentication mode="Forms">
       <forms loginUrl="~/account/logon"/>
    </authentication>

Here's a similar, but different question

Edit: I just tried manually entering in http://example.com/accout/login?cat=dog and it still redirected to an invalid URL : account/logon%3Fcat=dog. I originally thought it was related to a conflict between the membership provider and [RequireHttps] but it looks like just a basic bug so I think I'll have to just fix the source myself.

+1  A: 

Assuming this is a temporary bug in ASP.NET MVC 2 Preview 2 this is what I did :

  • Created RequireHttps2 class
  • Applied the [RequireHttps2] attribute instead of [RequireHttps]

    public class RequireHttps2Attribute : 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) { // only redirect for GET requests, otherwise the browser might not propagate the verb and request // body correctly.
    if (!String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
    {
        throw new InvalidOperationException("MUST USE SSL");
    }
    
    
    // redirect to HTTPS version of page
    UriBuilder builder = new UriBuilder()
    {
        Scheme = "https",
        Host = filterContext.HttpContext.Request.Url.Host,
        Path = filterContext.HttpContext.Request.Path,
        Query = filterContext.HttpContext.Request.QueryString.ToString()
    
    
        // ORIGINAL CODE : Path = filterContext.HttpContext.Request.RawUrl // use RawUrl since it works with URL rewriting
    
    
    };
    
    
    string url = builder.ToString();
    filterContext.Result = new RedirectResult(url);
    
    }

    }

Simon_Weaver
I had exactly the same problem, but this is the only post anywhere that I've seen that addressed it! Thanks.
ChrisW
did you try with MVC 2 RC yet? if not we need to file a bug report !
Simon_Weaver
+1  A: 

This appears fixed in ASP.NET MVC2 RC.

 /admin

now gets rewritten to the correct URL:

 /account/logon?ReturnUrl=/admin
Simon_Weaver