要做到這一點,我們有創建了一個ServiceFactory類,該類可連接到指定其端點的服務以及適當的接口。這假定你直接使用WCF服務,例如而不是通過VS生成的代理,因爲您需要在每個客戶端通道創建時設置用戶名和密碼值。
客戶端通道接口與服務工廠一起位於外部「服務庫」中,因此它們可以與WCF服務實現和客戶端共享。我們將這些憑證存儲在一個靜態字典中(儘管您也將它放在主資源字典中),並將密碼保存在SecuredString
中,以獲得一點額外的安全性。
我所描述的基本過程爲通過博客創建這樣一個服務工廠:
http://blog.kutulu.org/2012/03/proxy-free-wcf-ditching-proxy.html
在我們的例子中,我們在App.xaml.cs
,對於憑據提示進行安裝例程,使企圖調用我們的服務之一,循環直到我們獲得成功的登錄。該代碼要複雜得多,但它基本上是:
while (true)
{
var factory = new ChannelFactory<ITestChannel>(new WSHttpBinding("SecuredBinding"));
ITestChannel client = null;
try
{
factory.Credentials.UserName.UserName = logOnModel.UserName;
factory.Credentials.UserName.Password = logOnModel.Password;
var address = Settings.Default.TestServiceUrlBase));
client = factory.CreateChannel(address);
break;
}
// Catch various exceptions here.
}
在這裏的技巧是,如果你的賬號或密碼是錯誤的,你UsernamePasswordValidator
無法登錄,你會得到一個MessageSecurityException
將故障頻道,所以你需要關閉它並打開一個新的。但是,一旦打開了第一個頻道,您就無法更改ChannelFactory
上的憑據,因此您需要每次處理並重新創建新的工廠和新的客戶端頻道。
我們還在這裏查詢CommunicationException
和ArgumentException
以防萬一網址錯誤。
完成之後,您可以在服務工廠類中使用類似的代碼來構造客戶端,併爲其設置通道接口,併爲每個調用設置憑據。 (我們實際上爲每個不同的界面緩存服務工廠,因爲我們頻繁地創建和銷燬頻道,但這取決於您。)
在我們的案例中 - 客戶端是使用Visual Studio的「添加服務引用」創建的。在調用'Open()'方法之前,憑證會傳遞給生成的客戶端。所以 - 我不確定你的方法是否適合我的情況...... – 2012-07-09 13:44:53
你仍然可以使同一個想法奏效 - 一個創建你的頻道的工廠類 - 它不會那麼優雅。 VS服務引用確實爲其底層客戶端接口創建了一個「IClientChannel」接口,這可能有所幫助。或者你可以簡單地爲每個服務制定一個方法,如果這個數字足夠小的話。 – 2012-07-09 13:57:28
我有4項服務。這夠小嗎?我只是無法理解它是如何連接的。所以我有一個'Service Clients'的DLL,其中有工廠,但是誰啓動了它? 'LoginModel'?服務的實例存儲在哪裏? – 2012-07-09 14:00:48