2013-07-11 141 views
1

我一直在尋找這個問題的解決方案超過10個小時沒有答案。在我的應用程序中,我使用[requirehttps]屬性。當點擊一個用這個屬性裝飾的action方法時,我會在IE中看到「無法顯示網頁」,在深入研究這個問題之後,我發現我在Fiddler中接收到無限次的302調用,最終超時並導致錯誤。創建一個自定義屬性並物理創建https呼叫我使用IIS Express併成功創建了一個證書並綁定了端口如果我直接通過瀏覽器調用這個URL,一切正常,這是我用來重定向請求。MVC3重定向循環

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

你說的無限重定向循環是什麼意思? – ataravati

回答

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()); 
    } 
} 
+0

布倫特感謝您的回覆。在我創建這個自定義屬性之前,我使用RequiredHttps並仍然接收重定向循環。當IE通知我「該網站的安全證書存在問題」並且我點擊繼續時,瀏覽器中的URL仍然是http。點擊繼續後,無限重定向循環開始。我添加了你提到的附加條件檢查,它確實修復了重定向循環,但現在返回http而不是https。 – Aaron

+0

@Aaron我能夠重現這個問題,我最初的答案需要更多的重構,我已經編輯了答案。 –

+0

感謝工作的芽。真的很感激它。仍然不確定爲什麼RequiredHttps把我送到這條路上。我將不得不迴圈,並找出發生了什麼事情。 – Aaron