访问控制目的
在实际的组织中,为了完成组织的业务工作,需要在组织内部设置不同的职位,职位既表示一种业务分工,又表示一种责任与权利。根据业务分工的需要,职位被划分给不同群体,各个群体的人根据其工作任务的需要被赋予不同的职责和权利,每个人有权了解与使用与自己任务相关的信息与资源,对于那些不应该被知道的信息则应该限制他们访问。这就产生了访问控制的需求。
限制主体对资源的访问,限制用户可以访问而且只能访问自己被授权的资源,从而保障数据资源在合法范围内得以有效使用和管理。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。
访问控制策略
在权限管理中使用最多的还是基于角色访问控制(RBAC:Role Based Access Control)。基于角色的访问控制,是 20 世纪 90 年代研究出来的一种模型。这种模型的基本概念是把许可权(Permission)与角色(Role)联系在一起,用户通过充当合适角色的成员而获得该角色的许可权。
例如,在一间公司中,有老板、经理、行政、人事、财务等不同的职位,在通常情况下,职位所赋予的权利是不变的,但在某个职位上工作的人可以根据需要调整。RBAC 模型对组织内部的这些关系与访问控制要求给出了非常恰当的描述。
RBAC 重要对象
- 用户(Employee):角色施加的主体;用户通过拥有某个或多个角色以得到对应的权限。
- 角色(Role):表示一组权限的集合。
- 权限(Permission):一个资源代表一个权限,是否能访问该资源,就是看是否有该权限。
权限表设计
- id 主键
- 权限名称是给分配权限的人看的,用中文,见名知意。
- 权限表达式是给程序做判断的时候用的,用英文,并规定统一格式。
权限来源
要做资源的访问权限限制,其实就是对系统中的动态资源或者说控制器中的处理方法做限制,因为处理方法包含对数据库的 CRUD 操作。换句话说,控制器中的处理方法就是一个一个权限,即数据库中权限表的数据来源于所有控制器的一个一个处理方法。权限表达式的值需要具有唯一性,那么我们就约定权限表达式组成:控制器类名首字母小写除去 Controller 加上方法名,例如:department:list
,这样就可以唯一了。
权限数据录入
- 一条条手动添加太麻烦,需要用代码来批量添加。我们自定义一个注解,在控制器的处理方法上贴该注解,并直接在注解上设置权限名称和权限表达式,自己再定义第三方程序扫描这些贴了注解的方法,用程序录入数据。而且使用注解实现的好处:
- 一是可直接在注解上设置权限名称和权限表达式数据。
- 二是可标识哪些方法(资源)需要进行权限控制,区分一个处理方法是否要做权限限制,就看是否有贴注解,贴了代表要限制,反之不要,代表所有人能访问。
需求:程序根据代码自动生成权限数据,无须用户一条一条手动添加,实现步骤:
页面提供“权限加载”的按钮:
<a href="javascript:;" class="btn btn-success btn-reload" style="margin: 10px;">
<span class="glyphicon glyphicon-repeat"></span> 重新加载
</a>
- 给按钮绑定点击事件。
- 点击后使用确认框提示用户
加载时间可能较长,是否确认进行加载?
,用户确认后则发送请求到后台。 - 后台接收到请求后,则进行加载逻辑。代码逻辑思路如下:
- 获取 RequestMappingHandlerMapping 对象(直接用 @Autowired 注入),从该对象中获取所有的 HandlerMethod 对象(getHandlerMethods),判断方法是否有贴权限注解(getMethodAnnotation)。或者通过获取 Spring 容器对象(使用@Autowired 注入ApplicotionContext类型对象 ),再从中获取控制器对象(getBeansWithAnnotation(Controller.class).values()),获取所有的控制对象,遍历这个集合获得他们的字节码对象,反射获取所有控制器中的处理方法。
- 若贴有自定义注解,则从注解中获取权限名称和权限表达式,创建 Permission 对象,封装数据,并放入LinkedHasSet进行去重并保持顺序,先删除权限表里原有的权限,再将这个集合中的权限一次性插入到权限表中。
Spring MVC 应用启动时,会利用 RequestMappingHandlerMapping 对象,搜集并分析每个控制器中每个带 @RequestMapping 注解的处理方法,通过 HandlerMethod 来封装和表示该方法,并与注解中的映射路径一一绑定。HandlerMethod 封装了很多属性,可以方便的访问到请求方法、方法参数、方法上的注解、所属类等信息。
角色管理
新增新增
给这个角色分配权限
- 左边权限下拉框中显示所有的权限数据。
- 完成权限的左移右移功能。
- 角色保存时。按钮为普通按钮,绑定点击事件处理函数,在事件函数中把右边的 select 元素中的 option 设置为选中后,再提交表单,注意下拉框标签必须要拥有name属性,否则无法提交。
- 后台在保存角色时,还需要往角色权限中间表插入数据,保存角色和权限的关系。