亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET系列:RBAC權限設計

2019-11-14 14:27:58
字體:
來源:轉載
供稿:網友

權限系統的組成通常包括RBAC模型、權限驗證、權限管理以及界面訪問控制?,F有的一些權限系統分析通常存在以下問題:

(1)沒有權限的設計思路

認為所有系統都可以使用一套基于Table設計的權限系統。事實上設計權限系統的重點是判斷角色的穩定性和找出最小授權需求。角色的穩定性決定了系統是通過角色判斷權限還是需要引入RBAC方式,最小授權需求防止我們過度設計導致超出授權需求的權限粒度。

(2)沒有獨立的RBAC模型的概念

直接使用實體類表示RBAC模型,導致本身本應該只有幾行代碼且可以在項目級別復用的RBAC模型不僅不能復用,還要在每個項目無論是否需要都要有User、Role、Permission等實體類,更有甚者把實體類對應的數據表的結構和關聯當作權限系統的核心。

(3)權限的抽象錯誤

我們通常既不實現操作系統也不實現數據庫,雖然操作系統的權限和數據庫的權限可以借鑒,但一般的業務系統上來就弄出一堆增刪該查、訪問和執行這樣的權限,真是跑偏的太遠了。首先業務層次的操作至少要從業務的含義出發,叫瀏覽、編輯、審核等這些客戶容易理解或就是客戶使用的詞匯更有意義,更重要的是我們是從角色中按照最小授權需求抽象出來的權限,怎么什么都沒做就有了一堆權限呢。

(4)將界面控制和權限耦合到一起

開始的時候我們只有實體類Entities、應用服務Service以及對一些采用接口隔離原則定義的接口Interfaces,通常這個時候我們在Service的一個或多個方法會對應1個權限,這個時候根本界面還沒有,就算有界面,也是界面對權限的單向依賴,對于一個系統,可能不止有1個以上類型的客戶端,每個客戶端的界面訪問控制對權限的依賴都應該存儲到客戶端,況且不同的客戶端對這些數據各奔沒有辦法復用。

 下面我們使用盡可能少的代碼來構建一個可復用的既不依賴數據訪問層也不依賴界面的RBAC模型,在此基礎上對角色的穩定性和權限的抽象做一個總結。

1.創建RBAC模型

使用POCO創建基于RBAC0級別的可復用的User、Role和Permissin模型。

using System.Collections.Generic;namespace RBACExample.RBAC{    public class RBACUser    {        public string UserName { get; set; }        public ICollection<RBACRole> Roles { get; set; } = new List<RBACRole>();    }    public class RBACRole    {        public string RoleName { get; set; }        public ICollection<RBACPermission> Permissions { get; set; } = new List<RBACPermission>();    }    public class RBACPermission    {        public string PermissionName { get; set; }    }}

2.創建安全上下文

創建安全上下文RBACContext用于設置和獲取RBACUser對象。RBACContext使用線程級別的靜態變量保存RBACUser對象,不負責實體類到RBAC對象的轉換,保證復用性。

using System;namespace RBACExample.RBAC{    public static class RBACContext    {        [ThreadStatic]        PRivate static RBACUser _User;        private static Func<string, RBACUser> _SetRBACUser;        public static void SetRBACUser(Func<string, RBACUser> setRBACUser)        {            _SetRBACUser = setRBACUser;        }        public static RBACUser GetRBACUser(string username)        {            return _User == null ? (_User = _SetRBACUser(username)) : _User;        }        public static void Clear()        {            _SetRBACUser = null;        }    }}

3.自定義RoleProvider

自定義DelegeteRoleProvider,將權限相關的GetRolesForUserIsUserInRole的具體實現委托給靜態代理,保證復用性。

using System;using System.Web.Security;namespace RBACExample.RBAC{    public class DelegeteRoleProvider : RoleProvider    {        private static Func<string, string[]> _GetRolesForUser;        private static Func<string, string, bool> _IsUserInRole;        public static void SetGetRolesForUser(Func<string, string[]> getRolesForUser)        {            _GetRolesForUser = getRolesForUser;        }        public static void SetIsUserInRole(Func<string, string, bool> isUserInRole)        {            _IsUserInRole = isUserInRole;        }        public override string[] GetRolesForUser(string username)        {            return _GetRolesForUser(username);        }        public override bool IsUserInRole(string username, string roleName)        {            return _IsUserInRole(username, roleName);        }        #region NotImplemented        #endregion NotImplemented    }}

在Web.config中配置DelegeteRoleProvider

<system.web>    <compilation debug="true" targetFramework="4.5.2"/>    <httpRuntime targetFramework="4.5.2"/>      <authentication mode="Forms">      <forms loginUrl="~/Home/Login" cookieless="UseCookies" slidingExpiration="true" />    </authentication>    <roleManager defaultProvider="DelegeteRoleProvider" enabled="true">      <providers>        <clear />        <add name="DelegeteRoleProvider" type="RBACExample.RBAC.DelegeteRoleProvider" />      </providers>    </roleManager>  </system.web>

4.配置RBACContext和DelegeteRoleProvider

application_Start中配置RBACContext和DelegeteRoleProvider依賴的代理。為了便于演示我們直接創建RBACUser對象,在后文中我們再針對不同系統演示實體類到RBAC模型的映射。

    public class MvcApplication : System.Web.HttpApplication    {        protected void Application_Start()        {            RBACContext.SetRBACUser(u =>            {                return new RBACUser                {                    UserName = u,                    Roles = new List<RBACRole> {                        new RBACRole                        {                            RoleName="admin",                            Permissions = new List<RBACPermission> {                                new RBACPermission {                                     PermissionName="admin"                                }                            }                        }                    }                };            });            DelegeteRoleProvider.SetGetRolesForUser(userName => RBACContext.GetRBACUser(userName).Roles.SelectMany(o => o.Permissions).Select(p => p.PermissionName).ToArray());            DelegeteRoleProvider.SetIsUserInRole((userName, roleName) => RBACContext.GetRBACUser(userName).Roles.SelectMany(o => o.Permissions).Any(p => p.PermissionName == roleName));            AreaRegistration.RegisterAllAreas();            RouteConfig.RegisterRoutes(RouteTable.Routes);        }    }

5.在asp.net MVC中通過.NET API使用

User.IsInRoleAuthorizeAttribute此時都可以使用,我們已經完成了一個RBAC權限中間層,即隔離了不同系統的具體實現,也不用使用新的API調用。如果是服務層,使用Thread.CurrentPrincipal.IsInRole和PrincipalPermissionAttribute。

namespace RBACExample.Controllers{    public class HomeController : Controller    {        public ActionResult Login(string returnUrl)        {            FormsAuthentication.SetAuthCookie("admin", false);            return Redirect(returnUrl);        }        public ActionResult Logoff()        {            FormsAuthentication.SignOut();            return Redirect("/");        }        public ActionResult Index()        {            return Content("home");        }        [Authorize]        public ActionResult Account()        {            return Content(string.Format("user is IsAuthenticated:{0}", User.Identity.IsAuthenticated));        }        [Authorize(Roles = "admin")]        public ActionResult Admin()        {            return Content(string.Format("user is in role admin:{0}", User.IsInRole("admin")));        }    }}

6.擴展AuthorizeAttribute,統一配置授權

AuthorizeAttribute的使用將授權分散在多個Controller中,我們可以擴展AuthorizeAttribute,自定義一個MvcAuthorizeAttribute,以靜態字典保存配置,這樣就可以通過代碼、配置文件或數據庫等方式讀取配置再存放到字典中,實現動態配置。此時可以從Controller中移除AuthorizeAttribute。如前文所述,客戶端的訪問控制與權限的匹配應該存儲到客戶端為最佳,即使存放到數據庫也不要關聯權限相關的表。

namespace RBACExample.RBAC{    public class MvcAuthorizeAttribute : AuthorizeAttribute    {        private static Dictionary<string, string> _ActionRoleMapping = new Dictionary<string, string>();        public static void AddConfig(string controllerAction, params string[] roles)        {            var rolesString = string.Empty;            roles.ToList().ForEach(r => rolesString += "," + r);            rolesString = rolesString.TrimStart(',');            _ActionRoleMapping.Add(controllerAction, rolesString);        }        public override void OnAuthorization(AuthorizationContext filterContext)        {            var key = string.Format("{0}{1}", filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor.ActionName);            if (_ActionRoleMapping.ContainsKey(key))            {                this.Roles = _ActionRoleMapping[key];                base.OnAuthorization(filterContext);            }        }    }}

通過GlobalFilterCollection配置將MvcAuthorizeAttribute配置為全局Filter。

         public static void RegisterGlobalFilters(GlobalFilterCollection filters)        {            filters.Add(new HandleErrorAttribute());            MvcAuthorizeAttribute.AddConfig("AccountIndex");            MvcAuthorizeAttribute.AddConfig("AdminIndex", Permission.AdminPermission);            filters.Add(new MvcAuthorizeAttribute());        }

7.按需設計實體類

當RBAC模型不直接依賴實體類時,實體類可以按需設計,不再需要為了遷就RBAC的關聯引入過多的實體,可以真正做到具體問題具體分析,不需要什么系統都上Role、Permission等實體類,對于角色穩定的系統,既減少了系統的復雜度,也減少了大量后臺的功能實現,也簡化了后臺的操作,不用什么系統都上一套用戶頭疼培訓人員也頭疼的權限中心。

(1)使用屬性判斷權限的系統

有些系統,比如個人博客,只有一個管理員角色admin,admin角色是穩定的權限不變的,所以既不需要考慮使用多個角色也不需要再進行權限抽象,因此使用User.IsAdmin屬性代替Role和Permission就可以,沒必要再使用Role和Permission實體類,增大代碼量。后臺進行權限管理只需要實現屬性的編輯。

              RBACContext.SetRBACUser(u =>            {                var user = new UserEntity { UserName = "admin", IsAdmin = true };                var rbacUser = new RBACUser { UserName = user.UserName };                if (user.IsAdmin)                {                    rbacUser.Roles.Add(new RBACRole                    {                        RoleName = "admin",                        Permissions = new List<RBACPermission> {new RBACPermission {                                     PermissionName="admin"                                } }                    });                }                return rbacUser;            });

(2)使用角色判斷權限的系統

有些系統,比如B2C的商城,雖然有多個角色,但角色都是穩定的權限不變的,使用User和Role就可以,沒有必要為了應用RBAC而引入Permission類,強行引入雖然實現了Role和Permission的分配回收功能,但實際上不會使用,只會使用User的Role授權功能。權限的抽象要做到滿足授權需求即可,在角色就能滿足授權需求的情況下,角色和權限的概念是一體的。后臺實現權限管理只需要實現對用戶角色的管理。

(3)需要對角色進行動態授權的系統

有些系統,比如ERP,有多個不穩定的角色,每個角色通常對應多項權限,由于組織機構和人員職責的變化,必須對角色的權限進行動態分配,需要使用User、Role和Permission的組合。User由于權限范圍的不同,通常具有一個或多個權限,不同的User具有的角色通常不再是平行關系而是層級關系,如果不從Role中抽象Permission,需要定義大量的Role對應不同權限的組合,遇到這種情況時,分離權限,對角色進行權限管理就成了必然。后臺實現權限管理即需要實現對用戶角色的管理也需要實現對角色權限的管理。

              RBACContext.SetRBACUser(u =>            {                var user = ObjectFactory.GetInstance<IUserService>().GetUserByName(u);                return new RBACUser                {                    UserName = user.UserName,                    Roles = user.Roles.Select(r => new RBACRole                    {                        RoleName = r.RoleName,                        Permissions = r.Permissions.Select(p => new RBACPermission                        {                            PermissionName = p.Name                        }).ToList()                    }).ToList()                };            });

8.總結

使用RBAC模型和.NET的權限驗證API解決了權限系統的復用問題,從角色的穩定性出發防止實體類規模膨脹,通過最小授權需求的抽象可以防止權限的濫用。

參考:

(1)https://en.wikipedia.org/wiki/Role-based_access_control

(2)http://csrc.nist.gov/groups/SNS/rbac/faq.html

(3)http://www.codeproject.com/Articles/875547/Custom-Roles-Based-Access-Control-RBAC-in-ASP-NET

(4)http://www.ibm.com/developerworks/cn/java/j-lo-rbacwebsecurity/

Demo下載


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产视频久久久| 欧美高跟鞋交xxxxhd| 中文欧美在线视频| 久久久久久久久中文字幕| 欧美成人在线网站| 亚洲午夜精品视频| 日韩欧美国产黄色| 2019中文字幕在线观看| 日韩小视频网址| 久久国产精品偷| 国产成人jvid在线播放| 91精品国产色综合久久不卡98| 亚洲free性xxxx护士hd| 91免费国产网站| 91丨九色丨国产在线| 欧美大片网站在线观看| 欧美国产亚洲精品久久久8v| 福利精品视频在线| 热久久这里只有| 欧美午夜无遮挡| 欧美性受xxxx白人性爽| 成人黄色短视频在线观看| 欧美大片欧美激情性色a∨久久| 日韩电影免费在线观看| 国产精品h在线观看| 国外日韩电影在线观看| 国产精品毛片a∨一区二区三区|国| 日本一区二区三区在线播放| 亚洲第一精品夜夜躁人人爽| 欧美精品videosex性欧美| 国产成人久久久精品一区| 亚洲欧洲日产国产网站| 国模gogo一区二区大胆私拍| 日韩在线中文视频| 成人有码视频在线播放| 欧美另类第一页| 久久99久国产精品黄毛片入口| 国产精国产精品| 黑人狂躁日本妞一区二区三区| 亚洲直播在线一区| 97超碰国产精品女人人人爽| 亚洲天堂成人在线视频| 久久视频在线视频| 91精品国产综合久久香蕉最新版| 国产一区二区动漫| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲精品有码在线| 亚洲欧美综合精品久久成人| 欧美黑人狂野猛交老妇| 亚洲18私人小影院| 亚洲一区二区三区777| 亚洲欧洲在线看| 亚洲精品久久久久久久久久久| 欧美性极品少妇精品网站| 久久精品精品电影网| 中文字幕亚洲欧美日韩2019| 国产精品伦子伦免费视频| 亚洲精品二三区| 欧美成人亚洲成人日韩成人| 精品久久久久久久久久久| 奇米影视亚洲狠狠色| 亚洲曰本av电影| 精品五月天久久| 日韩av在线免费观看| 一区三区二区视频| 国产精品com| 亚洲free嫩bbb| 亚洲国产精品福利| 久久久久久久影视| 久久香蕉国产线看观看网| 亚洲精品资源在线| 国产成人一区二区三区| 亚洲第一男人av| 午夜精品福利在线观看| 色妞色视频一区二区三区四区| 亚洲国产精品va在看黑人| 一区二区成人精品| 国产精品亚洲自拍| 日韩小视频网址| 亚洲成人久久一区| 亚洲mm色国产网站| 91老司机精品视频| 自拍视频国产精品| 日韩av片永久免费网站| 久久久成人的性感天堂| 国产美女被下药99| 亚洲天堂免费在线| 欧美www视频在线观看| 亚洲一二三在线| 日韩午夜在线视频| 欧美巨大黑人极品精男| 欧美电影在线观看高清| 国内精品久久久久久影视8| 日韩在线一区二区三区免费视频| 成人乱人伦精品视频在线观看| 在线丨暗呦小u女国产精品| 亚洲韩国欧洲国产日产av| 成人网欧美在线视频| 色综合久久88色综合天天看泰| 爱福利视频一区| 蜜月aⅴ免费一区二区三区| www国产精品com| 成人av资源在线播放| 欧美亚洲国产日韩2020| 色播久久人人爽人人爽人人片视av| 伊人久久五月天| 国产精品一二区| 国产精品成人久久久久| 精品久久久香蕉免费精品视频| 精品久久久一区二区| www.日韩av.com| 久久午夜a级毛片| 国产精品久久一区| 日韩高清电影好看的电视剧电影| 亚洲最大福利视频| 亚洲欧美中文日韩在线| 国产精品麻豆va在线播放| 成人免费视频网址| 久久久天堂国产精品女人| 欧美精品videosex牲欧美| 国产欧美亚洲视频| 操日韩av在线电影| 日韩美女写真福利在线观看| 国产一区在线播放| 日韩最新免费不卡| 国产精品对白刺激| 欧美日韩黄色大片| 亚洲一区二区三区久久| 久久精品一本久久99精品| 国模精品视频一区二区三区| 国产精品美女在线| 精品无人国产偷自产在线| 亚洲国产欧美一区二区三区同亚洲| 亚洲国产成人精品女人久久久| 亚洲精品美女网站| xxxxxxxxx欧美| 国产日韩在线看| 久久国产精品99国产精| 亚洲小视频在线| 国产精品日日摸夜夜添夜夜av| 国产欧美精品在线播放| 国产精品夜色7777狼人| 爱福利视频一区| 国模叶桐国产精品一区| 欧美日韩午夜视频在线观看| 国内精品久久久久| 91精品国产91久久久久久最新| 国产精品自拍视频| 久精品免费视频| 久久色在线播放| 中文在线不卡视频| 亚洲日本中文字幕免费在线不卡| www.日韩欧美| 日韩av最新在线观看| 亚洲国产黄色片| 中文字幕国产精品久久| 亚洲国产成人久久| 久久九九免费视频| 国产亚洲精品激情久久| 精品久久久久久亚洲国产300| 另类视频在线观看| 精品日韩美女的视频高清| 亚洲天堂第一页| 亚洲va男人天堂|