本機測試完畢,準備將WCF部署到VM進行更多觀察,才誇WCF 4設定精簡,馬上踩到小圖釘。

沿續前文範例,將WcfWas部署到一台Windows 2012R2上,比照本機操作安裝「TCP啟用」設定IIS使用「http,net.tcp」協定,執行WCFClient程式,HTTP傳輸OK,執行net.tcp時產生「伺服器已經拒絕用戶端認證」錯誤。(英文:The server has rejected the client credentials)

爬文得知net.tcp預設連線時需完成身分驗證,不想跟驗證關卡糾纏(沒辦法,過去有太不好的回憶),決定先走匿名存取,修改WCFClient app.config,在netTcpBinding的bindingConfiguration中加入<security mode="None" />:

再試一次,錯誤訊息又變成「通訊端連線已中止。這可能是因為處理訊息時發生錯誤、或是遠端主機超過收逾時,或是基礎網路資訊問題所致。本機通訊端逾時是'00:00:59.1319179'。」(英文:The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '…')

缺乏經驗如我、一開始被逾時、基礎網路資源這些字眼迷惑,以為與封包大小、伺服器執行卡住或防火牆有關,爬文章後得到一項心得:「net.tcp出了任何差錯幾乎都是傳回這個鳥訊息」,這段訊息唯一告訴我們的就是「哦哦!某些地方壞掉了,快修好它」,問題是Server/Client端都找不到線索,這時我開始體會到前一篇文章說「HTTP比TCP容易偵錯」的意義。:P

猜想問題跟認證有關,剛才在WCFClient設好security mode="None",有可能Server端也需要設定。設定的過程,我得到第二項體會「WCF4的設定檔簡化是假象,一旦不用預設值就現出原形」!

如下圖所示,為了讓net.tcp免除身分驗證,得定義NetTcpBinding的Binding Configuration,宣告service的BasicHttpBinding及NetTcpBinding兩個endpoint,並將netTcpBinding的bindingConfiguration指向免驗證的額外設定。當net.tcp使用預設驗證,這一整段都可省略;一旦有部分需客製調整,得整段補上。

還有另一種做法是將netTcpBinding的security預設值改掉,如此可省掉<services>…</services>那一大段。寫法是binding不要指定name屬性(如下所示),代表要將netTcpBinding的預設值改為security mode="None":

<netTcpBinding>
  <binding>
    <security mode="None" />
  </binding>
</netTcpBinding>

但要注意修改預設值將影響所有WCF服務,有可能讓其他服務及endpoint不知不覺套用安全性較低的設定。

經過這番設定,終於成功完成跨機器的HTTP與TCP WCF呼叫囉~

如果想使用啟用驗證跑net.tcp該怎麼做?netTcpBinding預設的security mode為Transport,採Windows認證,所以只要確保「執行WCF Client的身分可以通過WCF Server的認證」即可過關,跟解決HTTP的Windows或MSDTC認證問題原理相似,得確保執行WCF Client的帳號能自動登入WCF Server所在Windows,一般有兩種做法:

  1. Client與Server都加入網域,使用網域帳號執行WCF Client
  2. 在Server建立相同名稱、相同密碼的帳號

WCF採Windows認證,非常適合應用在Windows Form/Console Application作為Client的情境,除了得知endpoint位址,使用者還必須具備Server認可的帳號,才允許使用WCF服務,安全大大加分。但若WCF Client為ASP.NET,指定執行身分不利管理,也易衍生額外風險,我較常用的做法是採security mode="None",但配合鎖定ASP.NET Server的IP,亦可維持一定程度的安全性。


Comments

Be the first to post a comment

Post a comment