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

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

ASP.NET系列:RBAC權限設計

2019-11-14 14:17:51
字體:
來源:轉載
供稿:網友

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

(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
欧美激情视频网| 国产视频精品免费播放| 亚洲伊人第一页| 国产在线播放不卡| 国产精品欧美日韩一区二区| 91久久中文字幕| 国外成人在线播放| 亚洲中国色老太| 国产一区二区在线免费视频| 久久久久九九九九| 日韩亚洲国产中文字幕| 欧美成人三级视频网站| 国产精品久久久久av免费| 亚洲成人国产精品| 亚洲精品动漫100p| 亚洲高清一区二| 欧美一区二区三区精品电影| 国产精品第100页| 欧美亚洲日本黄色| 国产精品27p| 久热在线中文字幕色999舞| 性金发美女69hd大尺寸| 欧美日韩国产在线播放| 亚洲老头老太hd| 久久这里只有精品视频首页| 国产精品免费一区| 久久综合五月天| 欧美久久久精品| 欧美日韩国产精品专区| 国模吧一区二区三区| 久久久久久久久中文字幕| 日韩欧美在线第一页| 亚洲第一偷拍网| 国产欧美日韩精品丝袜高跟鞋| 精品久久久久久久久久国产| 欧美黑人国产人伦爽爽爽| 国产成人久久精品| 精品国产一区久久久| 国产精品日韩欧美综合| 国产精品久久久久久久av电影| 欧美性猛交xxxx| 久久精品99久久久香蕉| 国产最新精品视频| 狠狠爱在线视频一区| 欧美国产日韩xxxxx| 国产精品入口尤物| 亚洲最大福利视频| 中文字幕最新精品| 欧美精品免费在线观看| 亚洲黄在线观看| 久久99国产精品久久久久久久久| 欧美激情精品久久久久久变态| 日韩中文在线中文网在线观看| www.久久色.com| 久久久免费精品视频| 国内精品一区二区三区| 亚洲一区av在线播放| 亚洲精品国产欧美| 国产精品色午夜在线观看| 清纯唯美亚洲激情| 成人欧美一区二区三区黑人孕妇| 国产精品爱久久久久久久| 亚洲区免费影片| 亚洲精品国产拍免费91在线| 日韩精品在线免费| 欧美激情三级免费| 国产日韩在线免费| 国产精品高清在线观看| 亚洲成人999| 久久精品视频在线播放| 国产精品99久久久久久白浆小说| 日韩av在线资源| 欧美激情aaaa| 一区二区三区视频在线| 欧美一区二区大胆人体摄影专业网站| 国产精品综合久久久| 久久久久久久久久久国产| 久久91亚洲精品中文字幕| 久久精品国产亚洲一区二区| 成人黄色免费在线观看| 久久av资源网站| 97精品视频在线观看| 亚洲成人网在线观看| 中文字幕精品久久| 欧美激情成人在线视频| 久久久久久久激情视频| 久久久久久噜噜噜久久久精品| 91九色在线视频| 奇米影视亚洲狠狠色| 日本成人黄色片| 日本欧美在线视频| 日韩高清av一区二区三区| 日韩美女写真福利在线观看| 久久网福利资源网站| 国产精品午夜一区二区欲梦| 富二代精品短视频| 亚洲国产精品一区二区久| 国产精品在线看| 国产精品入口日韩视频大尺度| 欧美视频免费在线观看| 国产精品久久色| 亚洲国产成人精品电影| 国产精品户外野外| 狠狠色噜噜狠狠狠狠97| 日韩精品视频在线播放| 久久精品免费电影| 亚洲精品一区中文字幕乱码| 欧美日韩亚洲一区二区三区| 夜夜躁日日躁狠狠久久88av| 国产精品视频自在线| 色噜噜狠狠狠综合曰曰曰| 国产精品一二区| 欧美精品久久久久a| 4p变态网欧美系列| 国产国语刺激对白av不卡| 国产欧美一区二区三区久久人妖| 亚洲japanese制服美女| 亚洲精品有码在线| 色七七影院综合| 欧美一区二区.| 亚洲人成亚洲人成在线观看| 欧美日韩国产精品一区二区三区四区| 欧美在线性爱视频| 久久精品国产一区二区电影| 国产精品久久久久久久av电影| 国产精品视频永久免费播放| 久久久影视精品| 91精品视频网站| 性欧美激情精品| 日本一区二区在线免费播放| 成人一区二区电影| 在线电影中文日韩| 日韩va亚洲va欧洲va国产| 亚洲精品乱码久久久久久按摩观| 国产一区视频在线| 国产成人综合精品在线| 91干在线观看| 国内自拍欧美激情| 性欧美长视频免费观看不卡| 亚洲电影免费在线观看| 国产精品视频免费在线观看| 狠狠躁夜夜躁久久躁别揉| 午夜精品久久久久久久久久久久久| 色视频www在线播放国产成人| 国产极品jizzhd欧美| 成人在线一区二区| 深夜精品寂寞黄网站在线观看| 中文字幕最新精品| 欧美成人免费va影院高清| 欧美激情一区二区三区在线视频观看| 欧美乱大交xxxxx另类电影| 成人免费直播live| 亚洲黄色成人网| 亚洲www永久成人夜色| 国产精品视频自拍| 18性欧美xxxⅹ性满足| 国产精品手机播放| 欧美成人免费视频| 国产91精品视频在线观看| 亚洲电影免费观看高清| 久久精品国产69国产精品亚洲| 久久久久久亚洲精品| 欧美性猛交xxxx久久久| 国产精品爽黄69天堂a|