views:

526

answers:

1

I am using an ActionFilter (see below) to detect whether or not 1. the current controller/action requires SSL and 2. SSL is currently being used, and redirect accordingly.

This works fine locally (using a dummy cert in IIS 7) but once I get it up on the server I get an error indicating an infinite redirect loop.

Any ideas?

 public class SslFilter : ActionFilterAttribute
{
    public SslFilter(bool sslRequired)
    {
        SslRequired = sslRequired;
    }

    public bool SslRequired { get; set; }


    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase req = filterContext.HttpContext.Request;
        HttpResponseBase res = filterContext.HttpContext.Response;

        var builder = new UriBuilder(req.Url);

        if (SslRequired && !req.IsSecureConnection)
        {
            builder.Scheme = Uri.UriSchemeHttps;
            builder.Port = 443;
            res.Redirect(builder.Uri.ToString());

        }
        else if (!SslRequired && req.IsSecureConnection)
        {
            builder.Scheme = Uri.UriSchemeHttp;
            builder.Port = 80;
            res.Redirect(builder.Uri.ToString());
        }

        base.OnActionExecuting(filterContext);
    }
}

Firefox error:

The page isn't redirecting properly

Firefox has detected that the server is redirecting the request for this address in a way that will never complete.

This problem can sometimes be caused by disabling or refusing to accept cookies.

+1  A: 

Try redirecting in a more MVCish way:

var builder = new UriBuilder(req.Url);

if (SslRequired && !req.IsSecureConnection)
{
    builder.Scheme = Uri.UriSchemeHttps;
    builder.Port = 443;
    filterContext.Result = new RedirectResult(builder.Uri.ToString());
    filterContext.Cancel = true;
}
else if (!SslRequired && req.IsSecureConnection)
{
    builder.Scheme = Uri.UriSchemeHttp;
    builder.Port = 80;
    filterContext.Result = new RedirectResult(builder.Uri.ToString());
    filterContext.Cancel = true;
}
else 
{
    base.OnActionExecuting(filterContext);
}
Darin Dimitrov
We tried this approach and Alex H's original approach - in both cases they worked in our dev environments but not in production. However, the accepted approach in this question did work - http://stackoverflow.com/questions/2302081/how-do-i-set-the-protocoll-when-using-redirecttoaction
Richard Ev