Spring Security 主要的功能是 认证
和 授权
,认证系列篇基本完结,接下来将进入 Spring Security 的授权系列篇。
本文主要介绍 常规权限系统的基本设计模型以及 Spring Security 的权限控制方案,话不多说,Let’s Go !!!
常规权限系统设计模型
系统应用不做权限管控,就犹如在大街上裸奔一般。
至今为止最普及的权限模型是 RBAC模型
,基于角色的访问控制(Role Based Access Control)。该模型主要含有3个实体,分别为: 用户
、角色
、权限
。
由模型图我们可以看出,三个实体分别是:用户、角色、以及权限;并且用户和角色之间是多对多的关系,角色和权限之间也是多对多的关系。
用户:发起操作的主体,比较常规的比如:系统的普通用户,管理员等。
角色: 拥有权限集的组合,用以连接用户和权限的桥梁;比如商城系统中管理员角色则有权限进行新增商品、下架商品等操作。
权限:用户可访问的资源,权限大体上可划分为:操作权限
、 数据权限
;操作权限是指页面上的功能按钮,例如:新增、删除、修改等。数据权限是指不同的用户在同一个页面下所看到的数据是不一样的。
可能有人会不理解,为什么在 用户
和 权限
之间多添加了一层 角色
的概念,不能直接将权限给到具体的用户吗?在系统规模比较小的情况下确实可以这么做,但当系统的用户上来后,就变得难以维护了。
比如新增一个1000个用户,需要为新用户设置查看个人信息、编辑个人信息、修改密码等权限,将权限赋给用户的操作会产生将近3000条的记录;而如果引入 角色
的概念,可以把查看个人信息、编辑个人信息、修改密码设置为 角色A
,给1000个新增用户授予 角色A
即可,这样1000个新增的用户都拥有了所需的权限,并且只产生1000条记录。
权限模型基本介绍完毕,那该如何将模型落地到实践中呢?
随着前后端分离架构的逐步成熟,越来越多的系统在架构选型上都采取了前后端分离的架构;那么在前后端分离的架构下,权限设计有什么需要注意的地方呢?
在前后端分离的场景下,页面的跳转统一由前端控制,后端只负责提供数据。怎么友好的告诉前端某个用户是否拥有某项操作的权限呢?这里我们对 RBAC模型
中的 权限
实体做了略微的调整,引入 Rest
风格,调整为 资源
。正如我们所知,前端页面上的操作按钮会一一映射到后端的接口上,我们只需要在 资源表
中维护相关接口的 URI
即可。
基于上述结论,我们可以设计出最核心的几张数据库表:用户表、用户角色关系表、角色表、角色资源关系表、资源表
建表语句如下所示(省略其他信息,只关注权限相关):
CREATE TABLE `user_info` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`username` varchar(255) DEFAULT NULL COMMENT '用户名',
`password` varchar(255) DEFAULT NULL COMMENT '密码',
`enabled` tinyint(1) DEFAULT 1 COMMENT '0不可用 1可用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '用户表'
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`name_en` varchar(64) NOT NULL DEFAULT '' COMMENT '角色名en',
`name_cn` varchar(64) NOT NULL DEFAULT '' COMMENT '角色名cn',
`enabled` tinyint(1) DEFAULT 1 COMMENT '0不可用 1可用',