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