| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
使用者認證管理設計方案 1 設計思路 為了設計一套具有較強可擴充性的使用者認證管理,需要建立使用者、角色和權限等資料庫表,并且建立之間的關系,具體實作如下。 1.1 使用者 使用者僅僅是純粹的使用者,用來記錄使用者相關資訊,如使用者名、密碼等,權限是被分離出去了的。使用者(User)要擁有對某種資源的權限,必須通過角色(Role)去關聯。 使用者通常具有以下屬性: ü 編号,在系統中唯一。 ü 名稱,在系統中唯一。 ü 使用者密碼。 ü 注釋,描述使用者或角色的資訊。 1.2 角色 角色是使用權限的基本機關,擁有一定數量的權限,通過角色賦予使用者權限,通常具有以下屬性: ü 編号,在系統中唯一。 ü 名稱,在系統中唯一。 ü 注釋,描述角色資訊 1.3 權限 權限指使用者根據角色獲得對程式某些功能的操作,例如對檔案的讀、寫、修改和删除功能,通常具有以下屬性: ü 編号,在系統中唯一。 ü 名稱,在系統中唯一。 ü 注釋,描述權限資訊 1.4 使用者與角色的關系 一個使用者(User)可以隸屬于多個角色(Role),一個角色組也可擁有多個使用者,使用者角色就是用來描述他們之間隸屬關系的對象。使用者(User)通過角色(Role)關聯所擁有對某種資源的權限,例如 l 使用者(User): UserID UserName UserPwd 1 張三 xxxxxx 2 李四 xxxxxx …… l 角色(Role): RoleID RoleName RoleNote 01 系統管理者 監控系統維護管理者 02 監控人員 線上監控人員 03 排程人員 排程從業人員 04 一般從業人員 從業人員 …… l 使用者角色(User_Role): UserRoleID UserID RoleID UserRoleNote 1 1 01 使用者“張三”被配置設定到角色“系統管理者” 2 2 02 使用者“李四”被配置設定到角色“監控人員” 3 2 03 使用者“李四”被配置設定到角色“排程人員” …… 從該關系表可以看出,使用者所擁有的特定資源可以通過使用者角色來關聯。 1.5 權限與角色的關系 一個角色(Role)可以擁有多個權限(Permission),同樣一個權限可配置設定給多個角色。例如: l 角色(Role): RoleID RoleName RoleNote 01 系統管理者 監控系統維護管理者 02 監控人員 線上監控人員 03 排程人員 排程從業人員 04 一般從業人員 從業人員 …… l 權限(Permission): PermissionID PermissionName PermissionNote 0001 增加監控 允許增加監控對象 0002 修改監控 允許修改監控對象 0003 删除監控 允許删除監控對象 0004 察看監控資訊 允許察看監控對象 …… l 角色權限(Role_Permission): RolePermissionID RoleID PermissionID RolePermissionNote 1 01 0001 角色“系統管理者”具有權限“增加監控” 2 01 0002 角色“系統管理者”具有權限“修改監控” 3 01 0003 角色“系統管理者”具有權限“删除監控” 4 01 0004 角色“系統管理者”具有權限“察看監控” 5 02 0001 角色“監控人員”具有權限“增加監控” 6 02 0004 角色“監控人員”具有權限“察看監控” …… 由以上例子中的角色權限關系可以看出,角色權限可以建立角色和權限之間的對應關系。 1.6 建立使用者權限 使用者權限系統的核心由以下三部分構成:創造權限、配置設定權限和使用權限。 第一步由Creator創造權限(Permission),Creator在設計和實作系統時會劃分。利用存儲過程CreatePermissionInfo(@PermissionName,@PermissionNote)建立權限資訊,指定系統子產品具有哪些權限。 第二步由系統管理者(Administrator)建立使用者和角色,并且指定使用者角色(User-Role)和角色權限(Role-Permission)的關聯關系。 1) 具有建立使用者、修改使用者和删除使用者的功能: Administrator l 存儲過程CreateUserInfo(@UserName,@UserPwd)建立使用者資訊; l 存儲過程ModifyUserInfo(@UserName,@UserPwd)修改使用者資訊; l 存儲過程DeleteUserInfo(@UserID)删除使用者資訊; 2) 具有建立角色和删除角色的功能: Administrator l 存儲過程CreateRoleInfo(@RoleName,@RoleNote)建立角色資訊; l 存儲過程DeleteRoleInfo(@RoleID)删除角色資訊; 3)Administrator具有建立使用者和角色、角色和權限的關聯關系功能: l 存儲過程GrantUserRole(@UserID,@RoleID,@UserRoleNote)建立使用者和角色的關聯關系; l 存儲過程DeleteUserRole(@UserRoleID)删除使用者和角色的關聯關系; l 存儲過程GrantRolePermission(@RoleID,@PermissionID,@RolePermissionNote)建立角色和權限的關聯關系; l 存儲過程DeleteRolePermission(@RolePermissionID)删除角色和權限的關聯關系; 第三步使用者(User)使用Administrator配置設定給的權限去使用各個系統子產品。利用存儲過程GetUserRole(@UserID, @UserRoleID output),GetRolePermission(@RoleID,@Role- -PermissinID output)獲得使用者對子產品的使用權限。 1.7 使用者認證實作 當使用者通過驗證後,由系統自動生成一個128位的TicketID儲存到使用者資料庫表中,建立存儲過程Login(@UserID,@UserPwd,@TicketID output)進行使用者認證,認證通過得到一個TicketID,否則TicketID為null。其流程圖如下: 圖1 Login流程圖 得到TicketID後,用戶端在調用服務端方法時傳遞TicketID,通過存儲過程JudgeTicketPermission(@TicketID,@PermissionID)判斷TicketID對應的使用者所具有的權限,并根據其權限進行方法調用。 當使用者退出系統時,建立存儲過程Logout(@UserID)來退出系統。當使用者異常退出系統時,根據最後的登陸時間(LastSignTime)确定使用者的TickeID,建立存儲過程ExceptionLogout(@UserID,@LastSignTime)處理使用者的異常退出。 圖2 Logout流程圖 WebService可以采用SoapHeader中寫入TicketID來使得TicketID從用戶端傳遞給服務端。.Net Remoting可以采用CallContext類來實作TicketID從用戶端傳遞給服務端。 2 資料庫設計 2.1 資料庫表 圖3 資料庫關系圖 2.2 資料庫表說明 2.2.1 使用者表(Static_User) Static_User
using System.Web.Services; using System.Web.Services.Protocols; // AuthHeader class extends from SoapHeader public class AuthHeader : SoapHeader { public string Username; public string Password; } public class HeaderService : WebService { public AuthHeader sHeader; ... } 服務中的每個 WebMethod 都可以使用 SoapHeader 自定義屬性定義一組關聯的标頭。預設情況下,标頭是必需的,但也可以定義可選标頭。SoapHeader 屬性指定公共字段的名稱或者 Client 或 Server 類的屬性(本标題中稱為 Headers 屬性)。在為輸入标頭調用方法前,WebService 設定 Headers 屬性的值;而當方法為輸出标頭傳回時,WebService 檢索該值。 [WebMethod(Description="This method requires a custom soap header set by the caller")] [SoapHeader("sHeader")] public string SecureMethod() { if (sHeader == null) return "ERROR: Please supply credentials"; else return "USER: " + sHeader.Username; } 然後,用戶端在調用要求标頭的方法之前,直接在代理類上設定标頭,如下面的示例所示: HeaderService h = new HeaderService(); AuthHeader myHeader = new AuthHeader(); myHeader.Username = "username"; myHeader.Password = "password"; h.AuthHeader = myHeader; String result = h.SecureMethod(); 3.2 .Net Remoting的安全認證方式 CallContext提供與執行代碼路徑一起傳送的屬性集,CallContext是類似于方法調用的線程本地存儲的專用集合對象,并提供對每個邏輯執行線程都唯一的資料槽。資料槽不在其他邏輯線程上的調用上下文之間共享。當 CallContext 沿執行代碼路徑往返傳播并且由該路徑中的各個對象檢查時,可将對象添加到其中。當對另一個 AppDomain 中的對象進行遠端方法調用時,CallContext 類将生成一個與該遠端調用一起傳播的 LogicalCallContext 執行個體。隻有公開 ILogicalThreadAffinative 接口并存儲在 CallContext 中的對象被在 LogicalCallContext 中傳播到 AppDomain 外部。不支援此接口的對象不在 LogicalCallContext 執行個體中與遠端方法調用一起傳輸。 CallContext.SetData方法存儲給定對象并将其與指定名稱關聯,CallContext.GetData方法從 CallContext 中檢索具有指定名稱的對象。 下面的代碼示例說明如何使用 SetData 方法将主體和辨別對象傳輸到遠端位置以進行辨別。 public class ClientClass { public static void Main() { GenericIdentity ident = new GenericIdentity("Bob"); GenericPrincipal prpal = new GenericPrincipal(ident, Newstring[] {"Level1"}); LogicalCallContextData data = new LogicalCallContextData(prpal); //Enter data into the CallContext CallContext.SetData("test data", data); Console.WriteLine(data.numOfAccesses); ChannelServices.RegisterChannel(new TcpChannel()); RemotingConfiguration.RegisterActivatedClientType( typeof(HelloServiceClass), "tcp://localhost:8082"); HelloServiceClass service = new HelloServiceClass(); if(service == null) { Console.WriteLine("Could not locate server."); return; } // call remote method Console.WriteLine(); Console.WriteLine("Calling remote object"); Console.WriteLine(service.HelloMethod("Caveman")); Console.WriteLine(service.HelloMethod("Spaceman")); Console.WriteLine(service.HelloMethod("Bob")); Console.WriteLine("Finished remote object call"); Console.WriteLine(); //Extract the returned data from the call context LogicalCallContextData returnedData = (LogicalCallContextData)CallContext.GetData("test data"); Console.WriteLine(data.numOfAccesses); Console.WriteLine(returnedData.numOfAccesses); } } 下面的代碼示例說明如何使用 GetData 方法将主體和辨別對象傳輸到遠端位置以進行辨別。 using System; using System.Text; using System.Runtime.Remoting.Messaging; using System.Security.Principal; public class HelloServiceClass : MarshalByRefObject { static int n_instances; int instanceNum; public HelloServiceClass() { n_instances++; instanceNum = n_instances; Console.WriteLine(this.GetType().Name + " has been created. Instance # = {0}", instanceNum); } ~HelloServiceClass() { Console.WriteLine("Destroyed instance {0} of HelloServiceClass.", instanceNum); } public String HelloMethod(String name) { //Extract the call context data LogicalCallContextData data = (LogicalCallContextData)CallContext.GetData("test data"); IPrincipal myPrincipal = data.Principal; //Check the user identity if(myPrincipal.Identity.Name == "Bob") { Console.WriteLine("/nHello {0}, you are identified!", myPrincipal.Identity.Name); Console.WriteLine(data.numOfAccesses); } else { Console.WriteLine("Go away! You are not identified!"); return String.Empty; } // calculate and return result to client return "Hi there " + name + "."; } } 4 詳細代碼設計 4.1 WebService代碼設計 WebService端代碼主要進行對資料庫的操作,建立起Client操作資料庫所需要的方法,供Client的端調用。 1)class UserInfoMng() 使用者資訊管理類,其中包括方法: l CreateUserInfo(string UserName string UserPwd) 建立使用者資訊,調用存儲過程CreateUserInfo(@UserName,@UserPwd) l ModifyUserInfo(string UserName string UserPwd) 修改使用者資訊,調用存儲過程ModifyUserInfo(@UserName,@UserPwd) l DeleteUserInfo() 删除使用者資訊,調用存儲過程DeleteUserInfo (@UserID) 2)class UserAuthentication() 使用者認證類,用來實作使用者角色、權限的設定,包括方法: l CreatePermissionInfo(string PermissionName string Permissi- -onNote) 建立權限資訊,調用存儲過程CreatePermissionInfo (@PermissionName,@PermissionNote) l CreateRoleInfo(string RoleName string RoleNote) 建立角色資訊,調用存儲過程CreateRoleInfo(@RoleName,@RoleNote) l DeleteRoleInfo() 删除角色資訊,調用存儲過程DeleteRoleInfo (@RoleID) l GrantUserRole(string UserID string RoleID string UserRoleNote) 授予使用者角色,調用存儲過程GrantUserRole(@UserID,@RoleID, @UserRoleNote) l DeleteUserRole() 删除使用者角色,調用存儲過程DeleteUserRole (@UserRoleID) l GrantRolePermission(string RoleID string PermissionID string RolePermissionNote) 授予角色權限,調用存儲過程GrantRolePermission(@RoleID,@PermissionID,@RolePermissionNote) l DeleteRolePermission() 删除授予的角色權限,調用存儲過程 DeleteRolePermission(@RolePermissionID) 4.2 使用者認證代碼設計(Client端) Client端調用WebService方法來進行資料庫通路,Client端代碼設計主要實作界面的功能,包括:權限設定、使用者管理、使用者授權管理和使用者認證管理 1)權限設定 class PermissionInfoMng() 使用者權限資訊管理類,包括方法: l CreatePermissionInfo() 建立權限資訊 2)使用者管理 class UserInfoMng() 使用者資訊管理類,包括方法: l CreateUserInfo() 建立使用者資訊 l ModifyUserInfo() 修改使用者資訊 l DeleteUserInfo() 删除使用者資訊 3)使用者授權管理 class RoleInfoMng() 角色資訊管理類,包括方法: l CreateRoleInfo() 建立角色資訊 l DeleteRoleInfo() 删除角色資訊 class UserRoleMng() 使用者角色管理類,包括方法: l GrantUserRole() 授予使用者角色 l DeleteUserRole() 删除使用者角色 class RolePermissionMng() 角色權限管理類,包括方法 l GrantRolePermission() 授予角色權限 l DeleteRolePermission() 删除角色權限 4)使用者認證管理 class Authentication() 使用者認證類,包括方法: l Login(string UserName string UserPwd) 使用者登陸認證,使用者認證通過配置設定給使用者一個TicketID,否則TicketID則為null l Logout() 使用者正常退出 l ExceptionLogout() 使用者異常退出 |