2011-08-29 67 views
19

我有一個WCF REST服務託管在Windows服務中,我想發送每個響應的Access-Control-Allow-Origin HTTP標頭(定義爲CORS的一部分)。WCF REST服務中的CORS支持

我試圖解決方案是有類似的IDispatchMessageInspector實現中的以下內容:

public void BeforeSendReply(ref Message reply, object correlationState) 
{ 
    var httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty; 
    if (httpResponse != null) 
    { 
     // test of CORS 
     httpResponse.Headers["Access-Control-Allow-Origin"] = "*"; 
    } 
} 

通常這會工作,但不幸的是我的服務也使用HTTP basic authorization,這意味着,當請求中沒有授權頭,WCF自動發送一個401響應請求憑據。不幸的是,在初始交換期間,WCF不會調用我的IDispatchMessageInspector,因此Access-Control-Allow-Origin頭不會添加到初始交換中。

當我嘗試從瀏覽器調用服務時,會出現此問題。 CORS指定只有在原始域與Access-Control-Allow-Origin響應標頭(*與所有域匹配)中列出的域匹配時才允許跨域請求。不幸的是,當瀏覽器在沒有Access-Control-Allow-Origin頭部的情況下看到最初的401響應時,它會阻止訪問(根據same origin policy)。

有沒有辦法給WCF自動發送的初始401響應添加一個頭?

+0

你有沒有遇到過這種情況? –

回答

6

要實現你想要的,你需要自己處理授權,這可能是通過推理+註冊一個HttpModule ...在那裏你會發出401並隨之發送你想要的任何http頭......甚至有一個這裏SO樣本實現 - 看Adding basic HTTP auth to a WCF REST service

編輯 - 從OP後評論:由於OP的評論

說,他是自承載的解決方案是不是HTTPModule但實際上IDispatchMessageInspector.BeforeSendReplyIDispatchMessageInspector.AfterReceiveRequest

授權必須配置爲「無」,並在IDispatchMessageInspector中自定義實施/處理 - 這樣,您可以在發出401時添加任何標頭。否則,處理基本身份驗證的運行時不會在正確/肯定的身份驗證之前調用您的IDispatchMessageInspector

雖然這個工程要注意的是,這意味着你自己實現安全sensitiv代碼,因此需要採取措施appriopriate以確保其正確實施...

+0

感謝您的回覆。我的服務需要成爲自託管的Windows服務,而不是IIS託管的服務。我的服務中的HTTP基本身份驗證工作非常棒。 CORS也可以正常工作(假設我禁用基本身份驗證)。只有在自託管服務上混合HTTP基本和CORS時纔會出現此問題。如果我要在IIS中託管服務,那麼我將配置IIS在每個請求上發送CORS響應標頭,並使用HTTP基本身份驗證的HttpModule。 – Kevin

+0

ok - 看我的編輯...你的解決方案已經是一半...你需要實現另一種方法,並改變配置... – Yahia

+0

設置clientCredentialType =「無」,並手動進行手動檢查幾乎工作。您可以發送401回覆,但WCF不允許您設置WWW-Authenticate響應標頭。試圖在代碼中設置WWW-Authenticate會導致WCF返回504。如果沒有WWW-驗證,瀏覽器將不會提示輸入憑據。 – Kevin

22

這傢伙救了我的一天。

http://blogs.microsoft.co.il/blogs/idof/archive/2011/07.aspx

我要放置一些在這裏他的筆記,以防萬一該網頁死亡的一天。 (我討厭發現「你的答案就在這裏」鏈接,然後將鏈接已經死了。)

<behaviors> 
    <endpointBehaviors> 
    <behavior name="webSupport"> 
     <webHttp /> 
     <CorsSupport /> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 
<extensions> 
    <behaviorExtensions> 
    <add name="CorsSupport" type="WebHttpCors.CorsSupportBehaviorElement, WebHttpCors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
</extensions> 
<services> 
    <service name="Service.JSonService"> 
    <endpoint address="http://localhost:8080" behaviorConfiguration="webSupport」 binding="webHttpBinding" contract="Service.IJSonService" /> 
    </service> 
</services> 

現在,你必須找到他所謂的「WebHttpCors.dll」下載庫。

但是,有足夠的(上面)來幫助你谷歌/ bing你的方式來解決。

扔我一個循環(在我的場景中)的部分是IE工作,但Firefox無法正常工作。

我的原始頁面爲:

http://localhost:53692/test/WCFCallTestViaJQ14.htm 

所以我的服務是:

http://localhost:8002/MyWCFService/MyWCFMethodByWebGet?state=NC&city=Raleigh 

所以我不得不本地主機< < - >>本地主機的流量。

****但港口是不同的。 (53692和8002)****

IE可以。 Firefox不適合它。

然後,你必須記住,每個瀏覽器處理他們的.Send()請求不同(在JQUERY裏面)。

這一切都有道理。

//JavaScript snipplet 

if (window.XMLHttpRequest) { 

    returnObject = new XMLHttpRequest(); 

} else if (window.ActiveXObject) { 

    returnObject = new ActiveXObject("Microsoft.XMLHTTP"); 

} else { 

msg = "Your browser doesn't support AJAX!"; 

} 

這裏有一些關鍵詞,我一直在使用googling/binging,最終導致我的某處。

Result: [Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIXMLHttpRequest.statusText]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://localhost:53692/test/WCFCallTestViaJQ14.htm :: HandleJQueryError :: line 326" data: no] 


XMLHttpRequest Send "NS_ERROR_FAILURE" 

JQuery Ajax WCF Self Hosted CORS JSON 
+0

Upvote的所有細節。保持良好的對抗鏈接腐爛! – codekaizen