RBAC許可權框架(Role-Based Access Control)基於角色的許可權訪問控制的框架,通過用戶-角色-許可權的關聯,非常方便的進行許可權管理,在這裡不再說明什麼是RBAC,請自行百度. 謝謝大家的捧場,如文章中有錯誤或者,請聯繫我或者給我發郵件[email protected],修正後 ...
RBAC許可權框架(Role-Based Access Control)基於角色的許可權訪問控制的框架,通過用戶-角色-許可權的關聯,非常方便的進行許可權管理,在這裡不再說明什麼是RBAC,請自行百度.
謝謝大家的捧場,如文章中有錯誤或者,請聯繫我或者給我發郵件[email protected],修正後將會有小禮品送出,謝謝
思路
小張、小王、小李要去動物園看動物,小張和小王提前在網上買好票了,小李沒買到票。
三人到了動物園公共展區,這裡不需要驗票,三人可以看這一片的動物(允許匿名訪問)。
繼續向前走,到了特別展區,需要驗證門票,小張和小王有門票順利的進入特別展區,小李被攔了下來(身份認證)。
小李不甘心啊,找了個角落,偷偷FQ景區,結果被景區人員抓了被帶到了警察局進行教育(非法訪問)。
小王在特別展區嫌慢,自己偷偷一不小心走到沒有許可權的地方而被抓。
相對關係
許可權:許可權是指是否允許可被訪問(被查看)和被使用的一種手段,通常設計具有上下級的關係,在本文中用的是樹形結構。
用戶:該操作系統的使用者,通過這個操作系統來完成某部分的工作生活。
角色:對用戶的一種分類,對許可權的一中整理,比如:普通員工有普通員工的許可權,經理又經理 的許可權。
在實際生活中,一個人有多個身份,比如,爸爸媽媽的孩子,孩子的父母,上班的職工等等。而一個公司的普通員工就有很多人。so,用戶和角色是多對多的關係。
而一個角色,也可能有多個許可權。比如,一個醫生除了治病救人之外,也可以醫療護理。一個警察在打擊犯罪的同時,也可以根據法律法規幫助別人。
而一個許可權,可能是多個角色擁有的。一個警察在打擊犯罪,普通市民也可以參與。往往一件事的事情(類比於一個許可權),會有多個角色的參與。
所以,角色和許可權也是多對多的關係
資料庫設計
因為是RBAC,所以肯定有用戶、角色、許可權,用戶和角色是多對多的關係,角色和許可權是多對多的關係。所以,需要有用戶表、用戶角色關聯表、角色表、角色許可權關聯表、許可權表。
用戶表:用戶代碼、用戶名、密碼。
角色表:角色代碼、角色名稱。
用戶角色關聯表:用戶代碼、角色代碼。
許可權表:許可權代碼、許可權名稱、鏈接地址、父級許可權代碼。
角色許可權關聯表:角色代碼、許可權代碼。
這些已經是基礎的表,往往生活工作中會比這複雜多了。在有的時候,還需要特殊用戶許可權關聯管理表。
程式的設計
根據需求,管理員可以管理許可權和維護用戶信息等,用戶可以實現自己的任務需求。
那麼,最基礎的是獲取許可權和判斷是否有相應的許可權,在頁面上展示相應 的功能呢以及在操作的時候判斷有木有操作的許可權。
比如管理員登陸,可以添加角色用戶許可權等。而用戶登錄,能夠管理商品,訂單的信息等。
環境
使用vs2015,sql server2017編程,Win10 Home x64系統軟體,相容IE8,IE9,IE10,谷歌瀏覽器等,使用PowerDesigner建模,等等
框架技術
整體框架使用了MVC+多層,頁面使用了MiniUI框架,考慮到用戶量不是很多,使用了Code First。
Code
由於保密條例,不展示業務部分,只有許可權
* 獲取許可權,用戶登錄後,根據用戶所屬的角色信息獲取相應的許可權。
* 判斷是否有許可權,在用戶進行操作前判斷是否有許可權
實現
*登錄: 用戶打開網站時,首先判斷當前頁面不允許匿名訪問,判斷Session是否有用戶會話信息,存在則載入用戶信息,不存在讀取Cookie,Cookie有登錄信息並且沒有過期,這載入用戶信息,否者跳轉登錄頁面
登錄成功之後或者載入完用戶信息之後,獲取許可權列表,顯示對應的模塊
* 操作: 當用戶點擊功能後或者在地址欄里輸入地址訪問,首先通過面向切麵編程的思路,使用動作過濾器或者許可權過濾器判斷是否有對應的許可權,有許可權就允許操作,沒有許可權則視為無效操作或者非法操作
無效操作: 返回上一頁或者上一步
非法操作: 清空登錄信息,清空Session,釋放Cookie,跳轉到非法訪問警告頁面,3秒後跳轉到登錄頁面
---------------- Common ----------------
1 public class UserPermissionFilter:System.Web.Mvc.ActionFilterAttribute 2 { 3 public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext) 4 { 5 #region 判斷是否有 此 controller 和 action 的許可權 6 LoginUserViewModel user = AdminUserBll.GetLoginUser(); 7 var permissionListAll = ModuleBll.Instance.GetLevelModuleListIsArrayAllInCache(); 8 if (null != user && !string.IsNullOrEmpty(user.user_name)) 9 { 10 bool ret = true; 11 if (user.PermissionList != null && user.PermissionList.Count > 0) 12 { 13 string action = filterContext.ActionDescriptor.ActionName; 14 string controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 15 string url = (controller + "/" + action).ToUpper(); 16 var module = permissionListAll.FirstOrDefault(c => c.action_url.ToUpper() == url); 17 if ((controller.ToUpper() != "HOME" && action.ToUpper() != "LOGIN") && 18 controller.ToUpper() != "MENU" && module != null) /*此Action下的不作許可權*/ 19 //&& module != null 20 { 21 ret = AdminUserBll.LoginUserIsPermission(controller, action, user); 22 } 23 if (!ret) 24 { 25 filterContext.HttpContext.Response.Redirect("/Home/NoRight", true); 26 //throw new System.Web.HttpException(403, "無權訪問"); 27 } 28 } 29 } 30 else 31 { 32 filterContext.HttpContext.Response.Redirect("/login", true); 33 34 } 35 36 37 #endregion 38 39 base.OnActionExecuting(filterContext); 40 } 41 }判讀是否有操作許可權
1 /// <summary> 2 /// 獲取全部一維的模塊View列表,在緩存中 3 /// </summary> 4 /// <returns></returns> 5 public List<LevelModuleViewModel> GetLevelModuleListIsArrayAllInCache() 6 { 7 return SystemCacheManager.GetCache("ModuleBll_GetLevelModuleListIsArrayAllInCache", 60, GetLevelMudleListIsArrayAll); 8 }在緩存中獲取模塊列表
1 public static class SystemCacheManager 2 { 3 /// <summary> 4 /// 5 /// </summary> 6 /// <param name="key"></param> 7 /// <param name="timeOut"></param> 8 /// <param name="function"></param> 9 /// <returns></returns> 10 public static T GetCache<T>(string key, int timeOut, Func<T> function) 11 { 12 if (string.IsNullOrEmpty(key)) return default(T); 13 var configs = HttpContext.Current.Cache[key]; 14 if (configs == null) 15 { 16 configs = function(); 17 if (timeOut > -1) 18 { 19 HttpContext.Current.Cache.Insert(key, configs, 20 null, DateTime.Now.AddSeconds(timeOut), 21 System.Web.Caching.Cache.NoSlidingExpiration); 22 } 23 else 24 { 25 HttpContext.Current.Cache.Insert(key, configs); 26 } 27 return (T)configs; 28 } 29 return (T)configs; 30 } 31 32 33 /// <summary> 34 /// 35 /// </summary> 36 /// <param name="key"></param> 37 /// <param name="timeOut"></param> 38 /// <param name="function"></param> 39 /// <returns></returns> 40 public static T GetCache<T,Z>(string key, int timeOut, Func<Z,T> function,Z u1) 41 { 42 if (string.IsNullOrEmpty(key)) return default(T); 43 var configs = HttpContext.Current.Cache[key]; 44 if (configs == null) 45 { 46 configs = function(u1); 47 if (timeOut > -1) 48 { 49 HttpContext.Current.Cache.Insert(key, configs, 50 null, DateTime.Now.AddSeconds(timeOut), 51 System.Web.Caching.Cache.NoSlidingExpiration); 52 } 53 else 54 { 55 HttpContext.Current.Cache.Insert(key, configs); 56 } 57 return (T)configs; 58 } 59 return (T)configs; 60 } 61 }獲取緩存數據
/// <summary> /// 判斷登錄用戶對請求是否有許可權 /// </summary> /// <param name="controller"></param> /// <param name="action"></param> /// <param name="login"></param> /// <returns></returns> public static bool LoginUserIsPermission(string controller, string action, LoginUserViewModel login) { if (login.PermissionList != null && login.PermissionList.Count > 0) { string strUrl = controller + "/" + action; if (login.PermissionList.FirstOrDefault(c => c.action_url.ToUpper() == strUrl.ToUpper()) != null) { return true; } } return false; }判斷用戶對當前請求是否有操作許可權
1 /// <summary> 2 /// 獲取登錄用戶 3 /// </summary> 4 /// <returns></returns> 5 public static LoginUserViewModel GetLoginUser() 6 { 7 if (System.Web.HttpContext.Current.Session["LoginUser"] != null) 8 { 9 return (LoginUserViewModel)System.Web.HttpContext.Current.Session["LoginUser"]; 10 } 11 else 12 { 13 string userName = Library.Web.Cookie.CookieManager.GetCookie(userCookieKey); 14 if (!string.IsNullOrEmpty(userName)) 15 { 16 userName = StringDes.DesDecrypt(userName); 17 AdminUserDb user = Instance.GetModel(userName); 18 if (user != null) 19 { 20 LoginUserViewModel view = Instance.IniLogin(user); 21 return view; 22 } 23 } 24 } 25 return new LoginUserViewModel(); 26 }在Session和Cookie中獲取登錄用戶
public ActionResult Login(string loginName, string passWord) { ViewBag.LoginName = loginName; ViewBag.PassWord = passWord; ViewBag.ErrorMessage = ""; string md5PassWord = Library.Tools.Text.StringMd5.Md5Hash32Salt(passWord); AdminUserDb user = AdminUserBll.Instance.GetModel(loginName); if (user != null) { if (user.pass_word.ToUpper() == md5PassWord.ToUpper()&&user.user_status==1) { user.last_lgoin_date = DateTime.Now; user.last_login_ip = Request.UserHostAddress; AdminUserBll.Instance.IniLogin(user); return RedirectToAction("Index", "Home"); } else { ViewBag.errorMessage = "用戶密碼錯誤"; } } else { ViewBag.errorMessage = "用戶密碼錯誤"; } return View(); }用戶登錄
1 /// <summary> 2 /// 獲取指定用戶名的用戶 3 /// </summary> 4 /// <param name="userName"></param> 5 /// <returns></returns> 6 public AdminUserDb GetModel(string userName) 7 { 8 9 return PermissionDal.GetModel(c => c.user_name == userName); 10 11 }獲取用戶信息
1 /// <summary> 2 /// 初始化登錄用戶 3 /// </summary> 4 /// <param name="user">登錄用戶</param> 5 /// <returns></returns> 6 public LoginUserViewModel IniLogin(AdminUserDb user) 7 { 8 if (user != null) 9 { 10 LoginUserViewModel loginUserViewModel = new LoginUserViewModel(); 11 loginUserViewModel.user_full_name = user.user_full_name; 12 loginUserViewModel.user_name = user.user_name; 13 List<ModuleDb> moduleDbList = ModuleBll.Instance.GetModuleList(user.user_name).ToList(); 14 if (moduleDbList != null && moduleDbList.Count > 0) 15 { 16 loginUserViewModel.PermissionList = moduleDbList; 17 loginUserViewModel.PermissionListLevel = ModuleBll.Instance.IniLevelModuleList(moduleDbList); 18 } 19 UpdateUserLogin(user); 20 System.Web.HttpContext.Current.Session["LoginUser"] = loginUserViewModel; 21 Library.Web.Cookie.CookieManager.SetCookie(userCookieKey, StringDes.DesEncrypt(loginUserViewModel.user_name)); 22 return loginUserViewModel; 23 } 24 return new LoginUserViewModel(); 25 }初始化用戶信息
1 --CREATE DATABASE center 2 --USE center 3 --GO 4 CREATE TABLE [dbo].[admin_user]( 5 [user_name] [nvarchar](50) PRIMARY KEY NOT NULL, 6 [pass_word] [nvarchar](100) NOT NULL, 7 [user_full_name] [nvarchar](100) NULL, 8 [user_status] [int] NOT NULL, 9 [last_lgoin_date] [datetime] NULL, 10 [last_login_ip] [nvarchar](255) NULL, 11 [creator_name] [nvarchar](50) NOT NULL, 12 [creator_date] [datetime] NOT NULL, 13 [modifi_name] [nvarchar](50) NULL, 14 [modifi_date] [datetime] NULL, 15 [user_img] [varchar](max) NULL 16 ) 17 GO 18 19 CREATE TABLE [dbo].[admin_user_role_relation]( 20 [id] [INT] PRIMARY KEY IDENTITY(1,1) NOT NULL, 21 [user_name] [nvarchar](50) NOT NULL, 22 [role_id] [int] NOT NULL, 23 [creator_name] [nvarchar](50) NOT NULL, 24 [creator_date] [datetime] NOT NULL 25 ) 26 GO 27 28 CREATE TABLE [dbo].[dictionary_table]( 29 [dt_key] [nvarchar](100) PRIMARY KEY NOT NULL, 30 [dt_type_key] [nvarchar](100) NOT NULL, 31 [dt_name] [nvarchar](100) NOT NULL, 32 [dt_status] [int] NOT NULL, 33 [dt_orderby] [decimal](18, 2) NOT NULL, 34 [creator_name] [nvarchar](50) NOT NULL, 35 [creator_date] [datetime] NOT NULL, 36 [modifi_name] [nvarchar](50) NULL, 37 [modifi_date] [datetime] NULL 38 ) 39 GO 40 41 CREATE TABLE [dbo].[dictionary_type_table]( 42 [dt_type_key] [nvarchar](100) PRIMARY KEY NOT NULL, 43 [dt_type_name] [nvarchar](100) NOT NULL, 44 [dt_type_remark] [nvarchar](200) NULL, 45 [dt_type_orderby] [decimal](18, 0) NOT NULL, 46 [creator_name] [nvarchar](50) NOT NULL, 47 [creator_date] [datetime] NOT NULL, 48 [modifi_name] [nvarchar](50) NULL, 49 [modifi_date] [datetime] NULL 50 ) 51 GO 52 53 CREATE TABLE [dbo].[module_db]( 54 [module_code] [nvarchar](50) PRIMARY KEY NOT NULL, 55 [module_name] [nvarchar](100) NOT NULL, 56 [parent_code] [nvarchar](50) NOT NULL, 57 [module_level] [int] NOT NULL, 58 [is_menu] [int] NOT NULL, 59 [is_action] [int] NOT NULL, 60 [action_url] [nvarchar](500) NULL, 61 [order_by] [decimal](10, 0) NOT NULL, 62 [module_status] [int] NOT NULL, 63 [creator_name] [nvarchar](50) NOT NULL, 64 [creator_date] [datetime] NOT NULL, 65 [modifi_name] [nvarchar](50) NULL, 66 [modifi_date] [datetime] NULL 67 ) 68 GO 69 70 CREATE TABLE [dbo].[role_db]( 71 [role_id] [INT] PRIMARY KEY IDENTITY(1,1) NOT NULL, 72 [role_name] [