![](/img/trans.png)
[英]WCF / wsHttpBinding / Message Security - BadTokenRequest
[英]load balancing WCF with wsHttpBinding and Message Security with client credentials type windows
我們有一個普通的WCF服務,其綁定看起來像這樣:
<wsHttpBinding>
<binding name="ServiceBinding" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxReceivedMessageSize="20971520"
messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
此服務位於負載均衡器后面的2台服務器中。 如此處所示
http://msdn.microsoft.com/en-us/library/vstudio/hh273122(v=vs.100).aspx
我已將establishSecurityContext設置為false。 當我運行調用服務時,我得到與無效安全上下文令牌相關的間歇性問題。 即使我說不要建立SeurityContext,似乎WCF正在做所有正常的握手事情。
此時使用Cert,BasicHttBinding或由於要求不允許安全性。
我甚至讓基礎架構團隊在負載均衡器中啟用粘性會話,但似乎沒有任何東西像我們期望的那樣工作。
我和我的團隊幾乎完成了互聯網上所說的一切,但是當有負載均衡器時似乎沒有任何工作,並且當沒有負載均衡器時這種綁定工作正常。
這個綁定有沒有運氣好嗎?
我們正在追逐微軟向我們發送WCF專家,但顯然人們很難掌握。
如何讓這個東西與Load Balancer很好地配合?
你設置negotiateServiceCredential =“true”。 這意味着在初始交換期間會創建安全上下文,但此上下文不會在后續調用中使用(因為establishSecurityContext =“false”)。 協商過程允許客戶端安全地獲取服務器憑據。 然后,客戶端使用這些憑據來保護消息。 這就是所有“握手的東西”發生的原因。
本文描述了此方案: “使用Windows客戶端的郵件安全性” 。
當您使用負載均衡器時需要進行安全協商(因為實際服務器的憑據取決於將為請求提供服務的計算機),除非您對平衡器后面的所有服務實例使用相同的憑據。 在后一種情況下,您可以設置negotiateServiceCredential =“false”並在配置或代碼中指定服務器憑據。 例如,您可以使用clientCredentialType =“Certificate”並為所有計算機使用相同的服務器證書。 或者你可以clientCredentialType =“Windows”並將任意SPN配置給域用戶,域用戶用於運行平衡器后面的所有服務(我沒有嘗試這種情況,請參閱下面的詳細信息)。
在你的情況下,negotiateServiceCredential =“true”。 所以可能的問題是:
1)粘性會話可能無法正常工作。 您可以通過使用返回的BasicHttBinding實現簡單的WCF服務來測試它
String.Format("{0}{1}", prefix, DateTime.Now);
在平衡器后面的一台服務器上的app設置中配置prefix =“”,前綴=“!!!!!!!!!!!!” 另外一個。 然后多次循環調用此服務並記錄結果。 您將看到粘性會話是否存在問題。
2)如果粘性會話正常工作,請確保在不使用平衡時,您的配置適用於所有服務器。
如果無法使用粘性會話,則應設置negotiateServiceCredential =“false”。 未使用協商,因此客戶端應在代碼或配置中顯式配置服務器憑據。 要在未經協商的情況下使用Windows憑據類型,服務的用戶帳戶必須能夠訪問向Active Directory域注冊的服務主體名稱(SPN)。 請參閱“使用沒有憑據協商的Windows客戶端的郵件安全性”中的詳細信息和示例
要使用任意SPN,您應將服務配置為在同一Windows域帳戶下運行。 要將任意SPN設置為帳戶,您可以在域控制器上使用setspn實用程序:
setspn a AcmeService/GlobalBank WS_Account
如Kerberos Technical Supplement for Windows中所述
有關各種方案和相應設置的說明,另請參閱有關Message Security的文章。
如上所述,一種選擇是關閉negotiateServiceCredential和establishSecurityContext。 這將導致性能損失,這可能對您的方案有意義,也可能沒有意義。 如果這種方法也不起作用,那么由於kerberos / ntlm可能沒有“一次性”認證。 我建議只為一個用戶操作(一個代理調用)打開Fiddler(或wcf日志),看看它是否只對服務器進行一次XML調用,或者是否需要多次調用進行身份驗證。
另一種選擇是確保所有服務器都使用Ivan提到的相同帳戶。
還有第三種選擇,通過使用無狀態安全上下文令牌使服務器無狀態。 剛設置:
requireSecurityContextCancellation=false
通過這種方式,所有客戶端每次都會將cookie發送到服務器,因此無論他們獲得哪個服務器都無關緊要。 我知道,對於證書安全性,這意味着所有服務器必須使用相同的證書,不確定Windows安全性中的含義是什么。 這是一個完整的例子:
http://msdn.microsoft.com/en-us/library/ms731814(v=vs.90).aspx
在某些情況下,創建自定義SecurityStateEncoder可能也是相關的:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.