1

我一直在寻找这个问题的解决方案超过 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。有任何想法吗?这让我发疯了。

4

1 回答 1

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());
    }
}
于 2013-07-12T00:44:28.203 回答