SpringBoot整合SpringSecurity实现权限控制(七):权限分配

本文详细介绍了如何在SpringBoot项目中整合SpringSecurity实现权限控制的权限分配功能,包括后端创建权限表、实现角色权限分配服务和接口,以及前端添加角色权限API、角色分配页面和动态生成菜单栏的逻辑。通过用户、角色和菜单的关联,实现精细化的权限管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章目录
《SpringBoot整合SpringSecurity实现权限控制(一):实现原理》
《SpringBoot整合SpringSecurity实现权限控制(二):权限数据基本模型设计》
《SpringBoot整合SpringSecurity实现权限控制(三):前端动态装载路由与菜单》
《SpringBoot整合SpringSecurity实现权限控制(四):角色管理》
《SpringBoot整合SpringSecurity实现权限控制(五):用户管理》
《SpringBoot整合SpringSecurity实现权限控制(六):菜单管理》


一、实现原理

  • 在前面的系列文章中,我们已经实现了用户管理、角色管理与菜单管理,接下来我们把这三个功能串起来:
  1. 通过权限分配把让角色关联到各个功能菜单。比如让系统管理员角色关联到用户管理、角色管理等菜单。
  2. 通过角色设置让用户关联到单个或多个角色。比如让张三用户关联到系统管理员角色。
  3. 用户关联到角色,角色关联到菜单,也即让用户间接拥有了系统的功能。

在这里插入图片描述

二、后端实现

2.1 创建权限表

  • 该表存储角色id与菜单id的关联信息
/**
 * 权限表
 *
 * @author zhuhuix
 * @date 2021-10-26
 */
@ApiModel(value = "权限信息")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_permission")
public class SysPermission {
   
   

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
	// 角色id
    private Long roleId;
	// 菜单id
    private Long menuId;

    private Timestamp createTime;

    public SysPermission(Long roleId, Long menuId, Timestamp createTime) {
   
   
        this.roleId = roleId;
        this.menuId = menuId;
        this.createTime = createTime;
    }
}

2.2 添加操作权限表的Mapper接口

  • 通过继承mybatis-plus的BaseMapper接口创建操作权限表的DAO接口,该BaseMapper接口已经包含了基本的增删改查操作。
/**
 * 权限表DAO接口
 *
 * @author zhuhuix
 * @date 2021-10-26
 */
@Mapper
public interface SysPermissionMapper extends BaseMapper<SysPermission> {
   
   

 // BaseMapper接口已经默认实现了基本的增删改查操作
}

2.3 实现角色权限分配的服务

  • 在原有角色管理的服务接口中加入获取角色权限与保存角色权限的接口.
/**
 * 角色信息接口
 *
 * @author zhuhuix
 * @date 2021-09-13
 * @date 2021-10-26 增加getPermission,savePermission
 */
public interface SysRoleService {
   
   

    ....

    /**
     * 获取角色权限
     *
     * @param roleId 角色id
     * @return 角色权限列表
     */
    List<SysPermission> getPermission(Long roleId);

    /**
     * 保存角色权限
     *
     * @param roleId 角色id
     * @param menus 权限表
     * @return 是否成功
     */
    Boolean savePermission(Long roleId,Set<Long> menus);

}
  • 实现获取角色权限与保存角色权限的接口
/**
 * 角色实现类
 *
 * @author zhuhuix
 * @date 2021-09-13
 * @date 2021-10-26 实现getPermission,savePermission接口
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysRoleServiceImpl implements SysRoleService {
   
   

    private final SysRoleMapper sysRoleMapper;
    private final SysPermissionMapper sysPermissionMapper;

    ...
    
    @Override
    public List<SysPermission> getPermission(Long roleId) {
   
   
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysPermission::getRoleId, roleId);
        return sysPermissionMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean savePermission(Long roleId, Set<Long> menus) {
   
   
        // 先根据roleId删除原有权限
        QueryWrapper<SysPermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysPermission::getRoleId, roleId);
        sysPermissionMapper.delete(queryWrapper);
        // 再插入roleId新权限
        for (Long menu : menus) {
   
   
            int rowCount = sysPermissionMapper.insert(
                    new SysPermission(roleId, menu, Timestamp.valueOf(LocalDateTime.now())));
            if (rowCount <= 0) {
   
   
                throw new RuntimeException("保存权限失败");
            }
        }

        return true;
    }
}

2.4 在Controller层添加访问API接口

在这里插入图片描述

/**
 * 角色信息api
 *
 * @author zhuhuix
 * @date 2021-09-13
 * @date 2021-10-26 增加getPermission,savePermission API接口
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/api/role")
@Api(tags = "角色信息接口")
public class SysRoleController {
   
   

    private final SysRoleService sysRoleService;

    ....

    @ApiOperation("获取角色权限信息")
    @GetMapping("{roleId}/permission")
    public ResponseEntity<Object> getPermission(@PathVariable Long roleId) {
   
   
        return ResponseEntity.ok(sysRoleService.getPermission(roleId));
    }

    @ApiOperation("保存角色权限信息")
    @PostMapping("{roleId}/permission")
    public ResponseEntity<Object> savePermission(@PathVariable Long roleId,@RequestBody Set<Long> menus) {
   
   
        return ResponseEntity.ok(sysRoleService.savePermission(roleId,menus));
    }
}

三、前端实现

3.1 添加角色权限api访问接口

  • 根据后端API,在角色信息api访问中添加读取权限与保存权限的接口
/**
 * 角色访问后端api
 * 2021-10-26 添加getPermission,savePermission
 */
import request from '@/utils/request'

...

export function getPermission(roleId) {
   
   
  return request({
   
   
    url: '/api/role/' + roleId + '/permission',
    method: 'get'
  })
}

export function savePermission(roleId, data) {
   
   
  return request({
   
   
    url: '/api/role/' + roleId + '/permission',
    method: 'post',
    data
  })
}

3.2 添加角色分配权限的页面

  1. 我们需要在原有角色信息的卡片列表中增加分配权限的按钮,用户点击按钮后弹出对应角色分配权限的操作页面。
    在这里插入图片描述
  2. 在弹出的操作页面上引用TreeSelect组件,加载系统的功能菜单,供用户选择。
    在这里插入图片描述
  3. 权限分配页面的完整实现代码
/**
* role/index.vue
* 2021-10-27 增加角色权限分配操作页面
*/
<template>
  <div class="app-container">
    <!--工具栏-->
    <div class="head-container">
      <!-- 搜索 -->
      <el-input
        v-model="roleName"
        size="small"
        clearable
        placeholder="输入角色名称搜索"
        style="width: 200px"
        class="filter-item"
        @keyup.enter.native="doQuery"
      />
      <el-date-picker
        v-model="createTime"
        :default-time="['00:00:00', '23:59:59']"
        type="daterange"
        range-separator=":"
        size="small"
        class="date-item"
        value-format="yyyy-MM-dd HH:mm:ss"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
      />
      <el-button
        class="filter-item"
        size="mini"
        type="success"
        icon="el-icon-search"
        @click="doQuery"
      >搜索</el-button
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

智慧zhuhuix

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值