上篇日志简单的使用了角色授予和权限授予,接下来,将通过数据库来管理用户对应的权限与角色。
权限表结构设计方式
第一种权限设计模型,权限和角色都考虑。数据库设计中,用户与角色是多对多的关系,角色与权限也是多对多的关系,而权限与资源是一对一的关系。它们的关系如下图所示。
graph LR 用户--关联-->角色--关联-->权限--关联-->资源
第二种权限设计模型,不考虑权限。用户与角色直接对应,是一种多对多的关系,通过不同的角色来对资源进行不同的限制这也是可以的,他们的关系如下所示。
graph LR 用户--关联-->角色
第三种模式权限设计模型,不考虑角色。用户与权限直接对应,也是一种多对多的关系。
graph LR 用户--关联-->权限
当然,或许还有更多的权限表结构方式。
接下来,咱们就使用第一种的方式来体验一把角色授予和权限授予吧。
数据库设计
首先是角色表,角色表的 DDL 如下所示。
create table t_role
(
id int auto_increment primary key,
name varchar(255) null comment '权限标识'
);
用户表与角色表的关联
create table t_user_role
(
id int auto_increment primary key,
userId int null comment '用户id',
roleId int null comment '角色id'
);
权限表的 DDL 如下所示
create table t_pers
(
id int auto_increment primary key,
name varchar(255) null,
url varchar(255) null comment '请求路径'
);
权限表与角色表的关联
create table t_role_perms
(
id int auto_increment primary key,
roleId int null,
permsId int null
);
表数据
角色表 SQL 数据
insert into shiro.t_role (id, name)
values (1, 'admin'),
(2, 'user'),
(3, 'product');
用户——角色表 SQL 关联数据
insert into shiro.t_user_role (id, userId, roleId)
values (1, 2, 1),
(2, 3, 3),
(3, 3, 2);
权限表 SQL 数据
insert into shiro.t_user_role (id, userId, roleId)
values (1, 2, 1),
(2, 3, 3),
(3, 3, 2);
权限——角色表 SQL 关联数据
insert into shiro.t_role_perms (id, roleId, permsId)
values (1, 1, 1),
(2, 1, 4),
(3, 2, 2),
(4, 3, 3);
权限和角色授予
给用户授予对应的权限和角色,对应 SQL 如下。
SELECT
t_user.id AS uid,
t_user.username,
t_role.id AS rid,
t_role.`name` AS `rolename`
FROM
t_user,
t_role,
t_user_role
WHERE
t_user.id = t_user_role.userId
AND t_user_role.roleId = t_role.id
AND t_user.username = #{username}
查询该角色对应的权限。
SELECT
t_pers.*
FROM
t_role_perms,
t_pers
WHERE
t_role_perms.roleId = #{roleId}
AND t_role_perms.permsId = t_pers.id
查询出来之后,在自定义的 Realm 中,利用 for 循环或者 foreach 方法来授予用户的角色。然后通过每一层循环来给当前的角色授予权限。
User user = userService.findRolesByUsername(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
if(user != null && !CollectionUtils.isEmpty(user.getRoles())) {
// 角色授予
user.getRoles().forEach(role -> {
authorizationInfo.addRole(role.getName());
// 权限授予
List<Pers> perms = userService.findPermsByRoleId(role.getId());
perms.forEach(pers -> {
System.out.println(pers);
authorizationInfo.addStringPermission(pers.getName());
});
});
return authorizationInfo;
}
这样一来,权限的授予就保存在数据库中了。当用户访问不同的页面时,就可以控制哪些资源不能访问,哪些资源允许访问。
请勿发布违反中国大陆地区法律的言论,请勿人身攻击、谩骂、侮辱和煽动式的语言。