SpringBoot-Security-用户权限分配-查找用户的菜单权限

简介: 本章实现的功能是,某个用户登录时,如何查找该用户的菜单权限 Spring security认证过程 1、用户使用用户名和密码进行登录。2、Spring Security将获取到的用户名和密码封装成一个实现了Authentication接口的UsernamePasswordAuthenticationToken。

本章实现的功能是,某个用户登录时,如何查找该用户的菜单权限

Spring security认证过程

1、用户使用用户名和密码进行登录。
2、Spring Security将获取到的用户名和密码封装成一个实现了Authentication接口的UsernamePasswordAuthenticationToken。
3、将上述产生的token对象传递给AuthenticationManager进行登录认证。
4、AuthenticationManager认证成功后将会返回一个封装了用户权限等信息的Authentication对象。
5、通过调用SecurityContextHolder.getContext().setAuthentication(...)将AuthenticationManager返回的Authentication对象赋予给当前的SecurityContext。
6、认证成功后,用户就可以继续操作去访问其它受保护的资源了,通过调用SecurityContextHolder.getContext().getAuthentication()获取保存在SecurityContext中的Authentication对象进行相关的权限鉴定。

系统权限设计

设计基础:任何权限的需求,都是为广义的用户分配角色,角色拥有广义的权限。用户、角色、菜单(权限)三大核心表,加上用户角色、角色菜单两个映射表。就可以通过登录的用户来获取权限列表,再间接获取用户菜单列表。

系统权限表结构设计如下

用户表

CREATE TABLE `crm_sys_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '系统用户名',
`password` varchar(60) NOT NULL COMMENT '密码',
`nickname` varchar(255) DEFAULT NULL COMMENT '昵称',
`headImgUrl` varchar(255) DEFAULT NULL COMMENT '头像',
`phone` varchar(11) DEFAULT NULL COMMENT '手机号',
`telephone` varchar(30) DEFAULT NULL COMMENT '电话',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`birthday` varchar(10) DEFAULT NULL COMMENT '生日',
`sex` tinyint(1) DEFAULT NULL COMMENT '性别',
`isEnable` int(1) DEFAULT NULL COMMENT '状态 0.已停用 1.正常',
`isDel` int(1) DEFAULT NULL COMMENT '是否删除(0.已删除 1.正常)',
`createTime` varchar(22) DEFAULT NULL,
`updateTime` varchar(22) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';

角色表

CREATE TABLE `crm_sys_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '角色名称',
`description` varchar(100) DEFAULT NULL COMMENT '描述',
`isEnable` tinyint(1) DEFAULT NULL COMMENT '状态 0.已停用 1.正常',
`isDel` tinyint(1) DEFAULT NULL COMMENT '是否删除(0.已删除 1.正常)',
`createTime` varchar(22) DEFAULT NULL,
`updateTime` varchar(22) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='系统角色表';

菜单表

CREATE TABLE `crm_sys_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parentId` int(11) NOT NULL COMMENT '上级菜单',
`name` varchar(50) NOT NULL COMMENT '菜单名称',
`css` varchar(30) DEFAULT NULL COMMENT '图标样式',
`href` varchar(1000) DEFAULT NULL COMMENT '链接',
`type` tinyint(1) NOT NULL COMMENT '菜单类型 1:菜单 2:按钮',
`permission` varchar(50) DEFAULT NULL COMMENT '按钮权限',
`sequence` int(11) NOT NULL COMMENT '排序',
`isEnable` int(1) DEFAULT NULL COMMENT '状态 0.已停用 1.正常',
`isDel` int(1) DEFAULT NULL COMMENT '是否删除(0.已删除 1.正常)',
`createTime` varchar(22) DEFAULT NULL,
`updateTime` varchar(22) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COMMENT='系统菜单表';

用户与角色关联表

CREATE TABLE `crm_sys_user_role` (
`userId` int(11) NOT NULL,
`roleId` int(11) NOT NULL,
PRIMARY KEY (`userId`,`roleId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统用户与角色关联表';

角色与菜单关联表

CREATE TABLE `crm_sys_role_menu` (
`roleId` int(11) NOT NULL,
`menuId` int(11) NOT NULL,
PRIMARY KEY (`roleId`,`menuId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统角色与菜单关联表';

查找用户的菜单权限树结构

业务代理

@GetMapping("/current")
public List<SysMenuDto> menuCurrent() {
    LoginUser loginUser = UserUtil.getLoginUser();
    Long id = Long.valueOf(String.valueOf(loginUser.getId()));
    List<SysMenuDto> list = iSysMenuService.listByUserId(id);
    final List<SysMenuDto> menus = list.stream().filter(l -> l.getType().equals(1))
            .collect(Collectors.toList());
    //支持多级菜单
    List<SysMenuDto> firstLevel = menus.stream().filter(p -> p.getParentId().equals(0)).collect(Collectors.toList());
    firstLevel.parallelStream().forEach(m -> {
        setChild(m, menus);
    });
    return firstLevel;
}

/**
 * 设置子元素
 * @param m
 * @param menus
 */
private void setChild(SysMenuDto m, List<SysMenuDto> menus) {
    List<SysMenuDto> child = menus.parallelStream().filter(a -> a.getParentId().equals(m.getId())).collect(Collectors.toList());
    m.setChild(child);
    if (!CollectionUtils.isEmpty(child)) {
        child.parallelStream().forEach(c -> {
            //递归设置子元素,多级菜单支持
            setChild(c, menus);
        });
    }
}

Authentication公用类

public class UserUtil {

public static LoginUser getLoginUser() {
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
    if (authentication != null) {
        if (authentication instanceof AnonymousAuthenticationToken) {
            return null;
        }

        if (authentication instanceof UsernamePasswordAuthenticationToken) {
            return (LoginUser) authentication.getPrincipal();
        }
    }

    return null;
}

}

sql代码

@Select("select distinct m.* " +
        "from crm_sys_menu m " +
        "inner join crm_sys_role_menu rm on m.id = rm.menuId " +
        "inner join crm_sys_user_role ru on ru.roleId = rm.roleId " +
        "where isDel = 1 and isEnable = 1 and ru.userId = #{userId} order by m.sequence")
List<CrmSysMenuPo> listByUserId(Long userId);

返回结果

[
{
"id": 1,
"parentId": 0,
"name": "系统管理",
"css": "fa-gears",
"href": "",
"type": 1,
"permission": "",
"sequence": 1,
"isEnable": true,
"isDel": true,
"createTime": "2017-10-05 21:59:18",
"child": [
  {
    "id": 2,
    "parentId": 1,
    "name": "用户",
    "css": "fa-users",
    "href": "sys/user/queryList",
    "type": 1,
    "permission": "",
    "sequence": 101,
    "isEnable": true,
    "isDel": true,
    "createTime": "2017-10-05 21:59:18",
    "child": [
      
    ],
    "serialVersion": -123142
  },
  {
    "id": 3,
    "parentId": 1,
    "name": "菜单",
    "css": "fa-cog",
    "href": "sys/menu/queryList",
    "type": 1,
    "permission": "",
    "sequence": 102,
    "isEnable": true,
    "isDel": true,
    "createTime": "2017-10-05 21:59:18",
    "child": [
      
    ],
    "serialVersion": -123142
  },
  {
    "id": 4,
    "parentId": 1,
    "name": "角色",
    "css": "fa-user-secret",
    "href": "sys/role/queryList",
    "type": 1,
    "permission": "",
    "sequence": 103,
    "isEnable": true,
    "isDel": true,
    "createTime": "2017-10-05 21:59:18",
    "child": [
      
    ],
    "serialVersion": -123142
  }
],
"serialVersion": -123142
}
]
目录
相关文章
|
1月前
|
JavaScript 安全 Java
Spring Boot 和 Vue.js 实现的前后端分离的用户权限管理系统
Spring Boot 和 Vue.js 实现的前后端分离的用户权限管理系统
53 0
|
1月前
|
存储 安全 前端开发
基于springboot的疫情物资捐赠和分配系统
基于springboot的疫情物资捐赠和分配系统
|
存储 关系型数据库 MySQL
springBoot+mysql实现用户权限控制--系统框架搭建(四)
springBoot+mysql实现用户权限控制--系统框架搭建(四)
|
安全 Java 数据安全/隐私保护
SpringBoot-Security-用户权限分配-配置验证规则
Spring Security配置 Spring Security配置是通过 @EnableWebSecurity注释和WebSecurityConfigurerAdapter共同提供基于网络的安全性。
5575 0
|
14天前
|
Java Linux
Springboot 解决linux服务器下获取不到项目Resources下资源
Springboot 解决linux服务器下获取不到项目Resources下资源
|
22天前
|
Java API Spring
SpringBoot项目调用HTTP接口5种方式你了解多少?
SpringBoot项目调用HTTP接口5种方式你了解多少?
71 2
|
22天前
|
前端开发 JavaScript Java
6个SpringBoot 项目拿来就可以学习项目经验接私活
6个SpringBoot 项目拿来就可以学习项目经验接私活
33 0
|
1月前
|
前端开发 Java 关系型数据库
SpringBoot+MyBatis 天猫商城项目
SpringBoot+MyBatis 天猫商城项目
54 1
|
1月前
|
JSON JavaScript 前端开发
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
解决js中Long类型数据在请求与响应过程精度丢失问题(springboot项目中)
37 0
|
25天前
|
Java Maven 微服务
springboot项目开启远程调试-jar包
springboot项目开启远程调试-jar包
19 0