索引
<a href="http://www.cnblogs.com/liulun/archive/2011/11/29/2268337.html">WinForm企業應用架構設計【一】界限劃分與動态建立WCF服務(no svc!no serviceActivations!)</a>
<a href="http://www.cnblogs.com/liulun/archive/2011/11/30/2269602.html">WinForm企業應用架構設計【二】團隊内部的約定和用戶端按約定識别WCF服務</a>
<a href="http://www.cnblogs.com/liulun/archive/2011/12/04/2275097.html">WinForm企業應用架構設計【三】架構窗體設計;動态建立菜單;</a>
<a href="http://www.cnblogs.com/liulun/archive/2011/12/08/2280110.html">WinForm企業應用架構設計【四】動态建立業務窗體</a>
<a href="http://www.cnblogs.com/liulun/archive/2011/12/16/2290800.html">WinForm企業應用架構設計【五】系統登入以及身份驗證+源碼</a>
閑話休提~
一:登入的畫面與用戶端邏輯

為了在打開程式的時候先彈出登入窗體
我們修改了主窗體的構造函數
如下:
登入窗體中登入和取消按鈕的事件代碼如下
當點選登入之後,
會把使用者輸入的使用者名和密碼傳迪到服務端,并得到目前使用者實體
CacheStrategy.CurUser = CurUser;
這裡隻是一個靜态屬性,沒有做額外的工作,就不多解釋了,
二:每次與WCF互動都傳遞辨別資訊
登入的過程其實沒有什麼特殊的
特殊的是,登入之後的每次服務端互動,
服務端都要确認目前的用戶端的正确性
為了做到這一點,
我們就要在每次與WCF互動的時候,
把用戶端的身份傳遞給伺服器端,并在服務端緩存起來。
我們修改了之前文章中提到的ClientFactory類
var curId = CacheStrategy.CurUser == null ? Guid.Empty : CacheStrategy.CurUser.Id;
MessageHeader<Guid> mhg = new MessageHeader<Guid>(Guid.Empty);
MessageHeader untyped = mhg.GetUntypedHeader("token", "ns");
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
這幾句為SOAP消息頭增加了一個值
這個值就是登入成功後的UserId
每次與WCF的互動操作都會傳遞這個值
三.服務端的驗證
為了對用戶端的操作進行身份驗證
我們設計了一個所有服務類的基類
虛方法CheckLogin負責驗證用戶端是否登入成功
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
此兩個類屬性放在服務基類裡
服務子類就不用再寫這兩個屬性了
var curId = OperationContext.Current.IncomingMessageHeaders.GetHeader<Guid>("token", "ns");
這一句得到了我們在用戶端傳上來的UserId
在登入邏輯的服務類裡,我們重寫了CheckLogin方法
因為登入的時候就不用再做驗證了,是以我們的重寫方法就沒有任何代碼
CacheStrategy.AddObject(result.Id, result);
就是把目前登入的使用者存入緩存裡
緩存我們用的是HttpRuntime的Cache
因為我們的WCF是基于WEB的
是以很自然的用了這個
代碼如下
四:用戶端對驗證消息的處理
在服務端基類裡我們對驗證不通過的客戶抛出了一個異常
throw new Exception("#請重新登入#");
(Exception這個類型的異常相對于其他類型的異常來說,是最後被處理的)
再來看看我們擷取所有菜單的代碼
當服務端有異常發生時,我們交給了Utils類去處理
如果異常,服務端“特意”傳回的
我們就讓用戶端重新登入
好吧!
就這些東西~
----------------------------------------
遺留問題
我試圖在ClientFactory中擷取服務端回報的錯誤
((IClientChannel)proxy).Faulted += new EventHandler(a_Faulted);
但這個事件是抓不到服務端錯誤消息的内容的
不能優美的解決用戶端對驗證消息的處理邏輯
這個系列到此将告一段落
以後或許我會寫增加更多東西
比如通用的權限、人事管理、定制表單、定制流程等
此為後話
我正在研究一個在silverlight上實作的類似的架構
已略有小成
再寫silverlight的東西
(透露一下,我已經把那個工具做成了,自由度非常高的打包工具,您可以用他來打包dotnet 2\3.5\4,以及其他的在系統資料庫裡留下痕迹的東西)
如各位所願
我公布出代碼和資料庫備份(親,資料庫是SQL2008的)
<a href="http://files.cnblogs.com/liulun/XL.zip">點此下載下傳</a>
親,也希望你們如我所願的幫我點推薦吧->->->->->->->->->->->->->->
因為你們的支援才是我的動力
歡迎與我交流!!!
-----------------------------------------