HTML5技术

ASP.NET 系列:RBAC权限设计 - #王刚

字号+ 作者:H5之家 来源:博客园 2016-01-30 11:59 我要评论( )

权限系统的组成通常包括RBAC模型、权限验证、权限管理以及界面访问控制。现有的一些权限系统分析通常存在以下问题: (1)没有权限的设计思路 认为所有系统都可以使用一套基于Table设计的权限系统。事实上设计权限系统的重点是判断角色的稳定性和找出最小授

权限系统的组成通常包括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 { RBACContext { [ThreadStatic] private static RBACUser _User; private static Func<string, RBACUser> _SetRBACUser; SetRBACUser(Func<string, RBACUser> setRBACUser) { _SetRBACUser = setRBACUser; } public static RBACUser GetRBACUser(string username) { return _User == null ? (_User = _SetRBACUser(username)) : _User; } 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; SetGetRolesForUser(Func<string, string[]> getRolesForUser) { _GetRolesForUser = getRolesForUser; } SetIsUserInRole(Func<string, string, bool> isUserInRole) { _IsUserInRole = isUserInRole; } [] GetRolesForUser(string username) { return _GetRolesForUser(username); } IsUserInRole(string username, string roleName) { return _IsUserInRole(username, roleName); } #region NotImplemented #endregion NotImplemented } }

在Web.config中配置DelegeteRoleProvider

4.配置RBACContext和DelegeteRoleProvider

Application_Start中配置RBACContext和DelegeteRoleProvider依赖的代理。为了便于演示我们直接创建RBACUser对象,在后文中我们再针对不同系统演示实体类到RBAC模型的映射。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    HTML5 进阶系列:拖放 API 实现拖放排序 - _林鑫

    2017-05-02 11:02

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    JS组件系列——自己动手封装bootstrap-treegrid组件 - 懒得安分

    2017-04-28 14:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

网友点评
a