为什么要进行访问控制
为了屏蔽无关人员操作系统的某个功能,防止误操作产生的垃圾数据或数据丢失。以电商后台为例,负责商品相关的工作人员,不允许他去操作订单相关的内容。同时,负责订单相关的工作人员,也不允许他去操作商品相关的内容。如果不进行权限控制,如果某一次,负责订单的工作人员去尝试操作商品相关的内容,就可能会造成垃圾数据产生(如发布一个错误的商品信息)或是数据丢失(删除了某个商品信息)的问题。
为了不产生这样的错误,让不同职责的工作人员各司其职,就需要进行访问控制。负责商品的账户,无法在页面看到以及操作订单相关的内容。负责订单的账户,无法在页面看到以及操作商品相关的内容。
RBAC(基于角色的访问控制)
角色就是权限的集合,某个角色就是某些权限的集合,目的是为了简化授权和鉴权的过程。
企业开发RBAC表结构
企业开发中的RBAC模型一般设置为7张表,4张基础表,3张关系中间表。
用户和角色
用户和角色之间是多对多关系,一个用户可以有多个角色,一个角色也可以属于多个用户,通过用户角色中间表进行关联。
用户表通常有这几个字段:id、账号、密码等
角色表通常有这几个字段:id、角色名等
角色和权限
角色和权限之间是多对多关系,一个角色可以拥有很多个权限,一个权限也可以被很多个角色拥有,通过角色权限中间表进行关联。
权限表(资源表)通常由这几个字段:id、资源Key(系统定义好的权限标识)、资源名称、上级资源id等、
权限和菜单
权限和菜单是多对多关系,一个权限可以访问多个菜单,一个菜单也可以被多个权限所访问,通过权限菜单中间表进行关联。
菜单表通常由这几个字段:id、菜单名、上级菜单id等
用户权限控制
当用户执行一个不存在的权限的url的时候,需要拦截请求。比如管理商品的用户,通过浏览器地址栏或是其他方式去执行订单管理的操作,这个是不允许的,需要拦截。
SpringSecurity权限控制
①基于URL的访问控制
在处理登录认证的时候,认证成功,根据id去查询对应角色的权限,加入权限列表。
// 创建权限列表
List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
// 添加权限
grantedAuths.add(new SimpleGrantedAuthority("goods_add"));
grantedAuths.add(new SimpleGrantedAuthority("goods_edit"));
grantedAuths.add(new SimpleGrantedAuthority("goods_delete"));
// ......
// 最后通过User返回
User user = new User(username,password,grantedAuths);
在配置文件中根据权限进行拦截
<!--
hasAnyAuthority():拥有任意权限都可以访问
hasAuthority('brand'):拥有brand的权限可以访问
hasAnyAuthority('goods_add','goods_edit'):拥有goods_add、goods_edit权限的可以访问
-->
<intercept‐url pattern="/*/find*.do" access="hasAnyAuthority()" />
<intercept‐url pattern="/goods/save.do" access="hasAnyAuthority('goods_add','goods_edit')" />
<intercept‐url pattern="/brand/*.do" access="hasAuthority('brand')" />
②基于方法的访问控制
需要配置启用注解配置
<global‐method‐security pre‐post‐annotations="enabled" />
然后在对应的权限控制的方法添加注解
@PreAuthorize("hasAuthority('goods')")