MVC3重定向循环

时间:2013-07-11 22:48:39

标签: asp.net-mvc iis https

我一直在寻找这个问题的解决方案超过10个小时而没有回答。在我的应用程序中,我使用[requirehttps]属性。当点击用这个属性装饰的动作方法时,我在IE中得到“无法显示网页”。在深入研究该问题之后,我看到我在Fiddler中接收到无限的302次调用,最终会超时并导致错误。所以我决定创建自定义属性并物理创建https调用。我正在使用IIS Express并成功创建了一个证书并绑定了端口。如果我直接通过浏览器调用此URL,一切正常。这是我用来重定向的代码请求。

public class HttpsAttribute : System.Web.Mvc.RequireHttpsAttribute
{
public bool RequireSecure = false;

public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext){
  var builder = new UriBuilder(HttpContext.Current.Request.Url);

  if (RequireSecure){
    // redirect to HTTP version of page         
    builder.Scheme = Uri.UriSchemeHttps;
    builder.Port = 44300;
    filterContext.Result = new RedirectResult(builder.Uri.ToString());
  }       
  else{         
    // non secure requested         
    if (filterContext.HttpContext.Request.IsSecureConnection){             
      HandleNonHttpRequest(filterContext);         
    }       
  }    
}    

protected virtual void HandleNonHttpRequest(AuthorizationContext filterContext){      
  if (String.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)){         
    // redirect to HTTP version of page         
    string url = "http://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;         
    filterContext.Result = new RedirectResult(url);      
  }   
}
}

当我设置断点以找出构建器值是什么时,它是正确的。它是从这里我收到一个无限重定向循环。奇怪的是,当我查看浏览器中的URL时,第一个请求永远不正确。就像UriBuilder没有发送正确的URL一样。有任何想法吗?这让我疯了。

1 个答案:

答案 0 :(得分:4)

重定向循环正在发生,因为代码仅检查是否需要HTTPS重定向,而不是当前请求已经是HTTPS(即重定向已经发生)。

if (RequireSecure && !filterContext.HttpContext.Request.IsSecureConnection){
  // redirect to HTTP version of page         
  builder.Scheme = Uri.UriSchemeHttps;
  builder.Port = 44300;
  filterContext.Result = new RedirectResult(builder.Uri.ToString());
}       
else{         
  // non secure requested         
  if (filterContext.HttpContext.Request.IsSecureConnection){             
    HandleNonHttpRequest(filterContext);         
  }       
} 

虽然RequireHttps应该可以正常工作,除非您需要重定向到指定的端口。

编辑: 重构属性

public class HttpsAttribute : System.Web.Mvc.RequireHttpsAttribute
{
    public bool RequireSecure = false;

    public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        var requestUri = HttpContext.Current.Request.Url;
        var requestIsSecure = HttpContext.Current.Request.IsSecureConnection;

        if (RequireSecure && !requestIsSecure)
            filterContext.Result = Redirect(requestUri, Uri.UriSchemeHttps, 44300);
        else if (!RequireSecure && requestIsSecure)
            filterContext.Result = Redirect(requestUri, Uri.UriSchemeHttp, 80);

    }

    private RedirectResult Redirect(Uri uri, string scheme, int port)
    {
        return new RedirectResult(new UriBuilder(uri) { Scheme = scheme, Port = port }.Uri.ToString());
    }
}