views:

144

answers:

2

I'm using MVC 1.0 and have created a "RequireSSLAttribute" (like the one in ASP.NET MVC 1.0 Futures but ignores SSL directives for local computer). I want to SSL-enable the sign up and login pages to protect the passwords that are being sent. However, I want the rest of the site to be non-SSL.

By adding the [RequireSSL] attribute to my controller's sign up and login methods, I am able to successfully get the app to redirect to the appropriate page with HTTPS. However, all pages after the sign up or login continue using SSL.

Is there any way to get the app to switch back to HTTP without having to create a "RequireNonSslAttribute" that I'd have to add to all of the other controller methods?

Thanks.

A: 

What if you just add it to the controller action that you redirect to after login? Or add a redirect in your base controller. For example, we do something like this in the base OnActionExecuting:

        if (req.IsSecureConnection && 
            filterContext.RouteData.Values["controller"]
                         .ToString().ToLower() != "home")
        {
            string url = req.Url.ToString().ToLower().Replace("http:", "https:");
            res.Redirect(url);
        }

This was the quickest way for us to accomplish basically the same thing (our home controller had the login-type actions).

Jess
This should work. The only problem I have now is that the action attribute in the form tag that's rendered by BeginForm creates a relative URL that isn't HTTPS. Looks like I'll have to override the action attribute with a HTTPS absolute URL using the overloaded version of the BeginForm method. Should work, but ugh.
goombaloon
A: 

In your ControllerBase class, you can override Controller.OnAuthorization and then check to see if the RequireHttps attribute (the RequireHttpsAttribute is new in MVC2) is set on the Controller Action. If the RequireHttps attribute is not set AND the request is under SSL, then return a redirect result to the non-ssl url. This way you do not have to set both a controller attribute and then put a controller.action name somewhere else.

protected override void OnAuthorization(AuthorizationContext filterContext)
{
    Boolean requireHttps = false;
    requireHttps = filterContext.ActionDescriptor.GetCustomAttributes(typeof(RequireHttpsAttribute), false).Count() >= 1;

    //the RequireHttpsAttribute set on the Controller Action 
    //will handle redirecting to Https.
    // We just need to handle any requests 
    //that are already under SSL but should not be.

    //If this request is under ssl but yet the controller action 
    // does not require it, then redirect to the http version.
    if (Request.IsSecureConnection && !requireHttps)
    {
        UriBuilder uriBuilder = new UriBuilder(Request.Url);

        //change the scheme
        uriBuilder.Scheme = "http";
        uriBuilder.Port = 80;

        filterContext.Result = this.Redirect(uriBuilder.Uri.AbsoluteUri);
    }


    base.OnAuthorization(filterContext);
}
Jeff Widmer