网上管理系统的权限设计似乎都是使用关系数据库的,这次我们的功能权限不再使用关系型数据库,直接使用对象数据库,体会一下面向对象的数据库在权限系统设计中的使用,因此也就不存在传统意义的数据库设计了。
直接看类图
在使用的时候只需这样
User user=new User("E0001"); if(user.hasPermissioin("R001001001")){ //执行R001001001所代表的功能操作,例如“添加工单”的操作 }
一般的只需要User<->Role<->Resource即可,这里加入了一个ResourceList是为了使系统更加灵活,将系统的开发和实施分开。由开发人员管理Resource,由系统的实施人员进行RescourceList的创建,由用户的权限管理员管理角色及给角色赋予RescourceList。当系统有成千上万的资源时,这样做几乎是必须的。
事情就这么解决了!不过还有一个问题,怎么管理需要进行权限验证的资源?难道每个都用 if(user.hasPermissioin("R001001001")) ?可以这么做,开发的时候对需要管控的程序部分写上 if(user.hasPermissioin("R001001001")) ,再在resources.xml文件中进行如下的配置。当上线的时候,实施人员也从resources.xml获取原始资源组成一个个许可权列表ResourceList。resources.xml可以非常简单
<resources> <resource id="R001001001" name="添加工单"/> <resource id="R001001002" name="修改工单"/> ... </resources>
这样做似乎也没什么问题,也不是太麻烦,只是程序中大量存在在if(user.hasPermissioin("R001001001")),并且还需要在resources.xml中填写资源名称,多了一层操作也就多了一个出错的可能,而且填写resources.xml似乎是一个比较傻瓜的事情,计算机就适合处理傻瓜的事情。
和xml作为配置文件有相似功能的是注解(C#中称为特性),在不需要经常修改配置(只能由开发人员修改)的场合使用注解会比xml文件配置合适,XML 会导致配置和代码人为地隔开了,查看源代码了解映射关系会很不方便。这里的权限设计正好是这样,程序中添加资源必然后导致resources.xml的修改,resources.xml的修改肯定也说明程序有了改动,也就是这个配置必然是开发人员改动的,注解/特性就非常的合适。
[Resource(Name="工单模块")] class WorkOrder{ [Resource(Name="创建工单")] public Create(){ } [Resource(Name="修改工单")] public Modify(){ } }
系统中有哪些需要管理的资源?直接反射含特性的类和方法,资源的ID直接用类名+方法名即可。当前用户有没有权限访问这个操作资源,直接在Resource特性中进行过滤即可。这样程序的开发就是个很happy的事情了,要纳入权限管理的类或方法,就在上面加一句 [Resource(Name="")]
如果系统非常庞大,又包含几个独立的子系统,那类似xml的配置文件可能还是少不了,需要灵活使用了。