Asp.net mvc MVC3重定向循环

Asp.net mvc MVC3重定向循环,asp.net-mvc,iis,https,Asp.net Mvc,Iis,Https,我一直在寻找一个解决这个问题的办法超过10个小时没有答案。在我的应用程序中,我使用[requirehttps]属性。单击带有此属性装饰的操作方法时,“我得到”无法显示网页"在IE中。在深入研究该问题后,我发现我在Fiddler中接收到无限302个调用,这最终会超时并导致错误。因此我决定创建一个自定义属性并实际创建https调用。我正在使用IIS Express并成功创建证书并绑定端口。如果我通过浏览器一切正常。这是我用来重定向请求的代码 public class HttpsAttribute :

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

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。有什么想法吗?这让我抓狂。

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

尽管
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());
    }
}

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

尽管
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());
    }
}

你说的无限重定向循环是什么意思?你说的无限重定向循环是什么意思?布伦特谢谢你的回答。在我创建这个自定义属性之前,我使用的是RequiredHttps,但仍然收到重定向循环。当IE通知我“这个网站的安全证书有问题”时我单击“继续”,浏览器中的URL仍然是http。单击“继续”后,无限重定向循环开始。我添加了您提到的附加条件检查,它确实修复了重定向循环,但现在返回的是http而不是https。@Aaron我能够重新创建该问题,我的初始答案需要更多的重构,我已经修改了我找到了答案。谢谢你,巴德。真的很感谢。仍然不知道为什么RequiredHttps会将我发送到这条路径。我将不得不返回,并找出这是怎么回事。布伦特感谢你的回复。在我创建此自定义属性之前,我使用RequiredHttps并仍然收到重定向循环。当IE通知我时“此网站的安全证书有问题”我单击“继续”,浏览器中的URL仍然是http。单击“继续”后,无限重定向循环开始。我添加了您提到的附加条件检查,它确实修复了重定向循环,但现在返回的是http而不是https。@Aaron我能够重新创建该问题,我的初始答案需要更多的重构,我已经修改了我找到了答案。谢谢你,巴德。真的很感谢。我仍然不知道为什么需要的HTTPS会让我走这条路。我必须回头看看到底是怎么回事。