WCF分布式開發常見錯誤(21):unable to open its IChannelListener.分發器未能打開偵聽器
我在進行WCF基於 UserName 和 Passoword的安全驗證編程的時候遇到這個 錯誤:
The ChannelDispatcher at 'http://localhost:8001/WCFService' with contract(s) '"IWCFService"' is unable to open its IChannelListener. 'http://localhost:8001/WCFService' with contract(s) '"IWCFService的 通道分發器未能通道打開偵聽器。WCF安全問題一直困擾很多人,相信很多WCF學 習者也對此非常頭疼。這個錯誤我嘗試了很久都沒有解決。後來我把此問題發到 WCF英文論壇,有個老外Rodrigo回答了我問題,但是沒有直接答案,算是給了我 一個提示。因為之前我猜測WCF安全模式裡可以不適用證書。因為WSE3.0裡我記 得就不需要使用。他告訴了WCF安全強制要求提供證書【1】原問題地址: http://social.microsoft.com/Forums/zh-CN/wcf/threads:
I have a question for WCF UserName and Passoword Validation.
I use Message security mode,but and NetTcpBinding,Console Selfhost.
But when I run the host application,Then throwed an exception:
The ChannelDispatcher at 'net.tcp://localhost:9001/WCFService' with contract(s) '"IWCFService"' is unable to open its IChannelListener.
I have try to solve it myself,But ,all methods are helpless,When I remove the codes in the config file it is ok :
<binding name="MessageAndUserName" >
<security mode="Message">
<message algorithmSuite="Basic256" clientCredentialType="UserName"/>
</security>
</binding>
is there anyone can give some tips?
Thanks a lot
錯誤截圖:
-----------------------------------------------------------------
【2】原因:
因為這裡WCF服務使用的安全模型為:Message。WCF要求消息安全必須提供證 書支持。而配置文件裡沒有設置。所以才出現這個錯誤。
我搜索的此錯誤的很多帖子,基本問題和解決方法都不清晰,導致這個問題 的原因很多。我最後把這個問題發到WCF的英文論壇,期待能有幫助的答案出現 。
【3】解決辦法:
要解決這個問題,根本還是需要解決證書的配置問題。因為使用的是XP環境 開發,所以證書配置比較麻煩,以前在做WSE3.0文章的時候,編寫代碼,也曾經 詳細學習過證書的制作。也准備了文章WSE3.0構建Web服務安全(2):非對稱加密 、公鑰、密鑰、證書、簽名的區別和聯系以及X.509 證書的獲得和管理,記錄了 詳細的證書制作過程。
今天這裡還是要使用到證書,主要問題就是要制作一個證書,然後在配置文 件裡進行配置。主要步驟如下:
(1)制作證書:
Microsoft Visual Studio 2008-->Visual Studio Tools-->Visual Studio 2008 命令提示行裡輸入:
makecert -r -pe -n "CN=FrankWCFServer" -ss My -sky exchange
具體的參數說明:詳細幫助文檔: http://msdn.microsoft.com/library/chs/default.asp? url=/library/CHS/cptools/html/cpgrfcertificatecreationtoolmakecertexe. asp
------------------------------------------------------------------ ------------------------------
-sr CurrentUser -- 證書存儲位置。Location 可以是 currentuser(默認值)或 localmachine
-ss My -- 證書存儲名稱,輸出 證書即存儲在那裡。My表示保存在“個人”
-n CN=MyTestCert -- 證書名稱。此名稱符合 X.500 標准。最簡單的 方法是在雙引號中指定此名稱,並加上前綴 CN=;例如,"CN=FrankXu"。
-sky exchange -- 指定頒發者的密鑰類型,必須是 signature、exchange 或一個表示提供程序類型的整數。默認情況下,可傳入 1 表示交換密鑰,傳入 2 表示簽名密鑰。
-pe -- 私鑰標記為可 導出。這樣私鑰包括在證書中。
------------------------------------------------------------------ -----------------
這個命令生成一個名字為FrankWCFServer的證書,被保存到了當前用戶的個 人證書存儲區內。一般我們自己開發使用的Windows證書服務來管理和獲取證書 。
運行成功以後,這裡可以再浏覽器--工具--選項裡查看證書:
(2)設置證書:在WCF服務的配置文件裡,設置對應的證書。直接在WCF服務 端證書節點裡添加如下代碼即可:
<serviceCertificate x509FindType="FindBySubjectName" findValue="FrankWCFServer" storeLocation="CurrentUser"/>
整個服務的參考代碼如下:
<services>
<service behaviorConfiguration="WCFService.WCFServiceBehavior"
name="WCFService.WCFService">
<endpoint
address="http://localhost:8001/WCFService"
binding="wsHttpBinding" bindingConfiguration="MessageAndUserName" contract="WCFService.IWCFService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8002/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFService.WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate x509FindType="FindBySubjectName" findValue="MyServer" storeLocation="CurrentUser"/>
<clientCertificate >
<authentication certificateValidationMode="None" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFService.MyUserNamePasswordVali dator,WCFService" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="MessageAndUserName" >
<security >
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
【4】總結:
WCF安全開發一直是比較復雜的問題,因為不論相對於以前的Web Service 在 Soap Header消息裡封裝UserName和Password的簡單方式 ,還是和WSE3.0的直 接提供 UserName和Password的Validation比較,都復雜了不少,這裡主要涉及 的是證書的設置和使用。對很多只是在XP環境下開發的學習者來說,證書的制作 和安裝已經是困難重重,何況還要理解一堆證書相關的安全的概念,包括加密算 法、簽名等一系列概念,很多人在學WCF安全開發的時候都會感覺無所適從,遇 到問題也很難解決。詳細的資料和可執行示例代碼很少,幾乎權威的參考文檔都 是英文。理解也非常困難。這個錯誤相信很多朋友也遇到過,就整理出來大家一 起參考。