springboot集成spring security初探2--从数据库读取用户权限

时间:2024-04-13 10:42:19

上一篇文章只是实现了 UserDetailService 接口,简单new 了一个 User,并没有连接数据库来验证用户信息和权限。本篇将详细介绍连接数据库之后的认证操作。

RBAC权限控制,涉及到用户(User)、角色(Role)和权限(Permission)三个实体,这三个实体是相互独立的,直到将用户关联上了角色,将角色关联上了权限,形成Role_User和Role_Permission 的关系。对应到数据库表上,则需要建立相应的5张数据表。我的例子中的表结构如下所示:

用户表:
CREATE TABLE `operation_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户 id',
  `user_name` varchar(45) NOT NULL COMMENT '用户姓名',
  `pwd` varchar(50) NOT NULL COMMENT '密码',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4

角色表:
CREATE TABLE `role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色 id',
  `role_name` varchar(45) NOT NULL COMMENT '角色名称',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

权限表:
CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限 id',
  `name` varchar(45) DEFAULT NULL COMMENT '权限名称',
  `description` varchar(45) DEFAULT NULL COMMENT '权限描述',
  `url` varchar(45) DEFAULT NULL COMMENT '资源 url',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

用户-角色关系表:
CREATE TABLE `role_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '用户 id',
  `role_id` int(11) NOT NULL COMMENT '角色 id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4

角色-权限关系表:
CREATE TABLE `role_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(11) NOT NULL COMMENT '角色 id',
  `perm_id` int(11) NOT NULL COMMENT '权限 id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4
以上是表结构。

以下是 spring security 工作机制大致示意图,便于在整体上有个概念。https://www.processon.com/view/5a0551c2e4b06bed41ceef0e

springboot集成spring security初探2--从数据库读取用户权限


springboot集成spring security初探2--从数据库读取用户权限
根据以上流程示意图,需要实现以下类:
(1)——(5)参考资源:http://blog.****.net/code__code/article/details/53885510,http://blog.****.net/u012373815/article/details/54633046


(1)MySecurityFilter,继承AbstractSecurityInterceptor,实现Filter接口。功能:拦截登录之后的 url,实际上登录的 url 也拦截了(从我的这个例子来看),注入MyAccessDecisionManager的 bean。
(2)MyInvocationSecurityMetadataSourceService ,功能:加载所有权限,判断某个 url 是否在权限表中,如果在的话则判断该用户是否有权限访问,要调用MyAccessDecisionManager类中的decide 方法。
(3)MyAccessDecisionManager,功能:判断用户是否有权限访问。
(4)MyUserDetailServiceImpl实现UserDetailsService接口,重写loadUserByUsername方法,功能:从数据库里查询是否存在该用户,判断密码是否一致,读取该用户权限。
(5)SecurityConfig,继承WebSecurityConfigurerAdapter,功能:注入(1)(4)(6)的bean,配置 HttpSecurity资源访问规则。
(6)MyAccessDeniedHandler实现AccessDeniedHandler接口,重写 handle 方法,功能:返回自定义的403页面。

参考资源:http://blog.****.net/jiangshanwe/article/details/73234988,http://dianfusoft.iteye.com/blog/2008721


因为代码比较多,我就直接把项目完整代码放到 git (https://github.com/weichaolei/springboot-spring-security)上。供大家参考,写的不妥之处,欢迎大家批评指正。