refactor: 用户权限方案重构,黑名单实现 JWT 主动注销
This commit is contained in:
@@ -17,7 +17,7 @@ import com.youlai.system.security.util.JwtUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
@@ -43,7 +43,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class AuthServiceImpl implements AuthService {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
private final RedisTemplate<String,Object> redisTemplate;
|
||||
private final CodeGenerator codeGenerator;
|
||||
private final Font captchaFont;
|
||||
private final CaptchaProperties captchaProperties;
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.youlai.system.model.form.MenuForm;
|
||||
import com.youlai.system.model.query.MenuQuery;
|
||||
import com.youlai.system.model.vo.MenuVO;
|
||||
import com.youlai.system.model.vo.RouteVO;
|
||||
import com.youlai.system.security.service.PermissionService;
|
||||
import com.youlai.system.service.SysMenuService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -42,6 +43,8 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
||||
|
||||
private final MenuConverter menuConverter;
|
||||
|
||||
private final PermissionService permissionService;
|
||||
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
@@ -199,18 +202,17 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
||||
@Override
|
||||
@CacheEvict(cacheNames = "menu", key = "'routes'")
|
||||
public boolean saveMenu(MenuForm menuForm) {
|
||||
String path = menuForm.getPath();
|
||||
|
||||
MenuTypeEnum menuType = menuForm.getType();
|
||||
|
||||
// 如果是目录
|
||||
if (menuType == MenuTypeEnum.CATALOG) {
|
||||
if (menuType == MenuTypeEnum.CATALOG) { // 如果是外链
|
||||
String path = menuForm.getPath();
|
||||
if (menuForm.getParentId() == 0 && !path.startsWith("/")) {
|
||||
menuForm.setPath("/" + path); // 一级目录需以 / 开头
|
||||
}
|
||||
menuForm.setComponent("Layout");
|
||||
}
|
||||
// 如果是外链
|
||||
else if (menuType == MenuTypeEnum.EXTLINK) {
|
||||
} else if (menuType == MenuTypeEnum.EXTLINK) { // 如果是目录
|
||||
|
||||
menuForm.setComponent(null);
|
||||
}
|
||||
|
||||
@@ -218,7 +220,14 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
||||
String treePath = generateMenuTreePath(menuForm.getParentId());
|
||||
entity.setTreePath(treePath);
|
||||
|
||||
return this.saveOrUpdate(entity);
|
||||
boolean result = this.saveOrUpdate(entity);
|
||||
if (result) {
|
||||
// 编辑刷新角色权限缓存
|
||||
if (menuForm.getId() != null) {
|
||||
permissionService.refreshRolePermsCache();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,10 +294,18 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
||||
@Override
|
||||
@CacheEvict(cacheNames = "menu", key = "'routes'")
|
||||
public boolean deleteMenu(Long id) {
|
||||
return this.remove(new LambdaQueryWrapper<SysMenu>()
|
||||
.eq(SysMenu::getId, id)
|
||||
.or()
|
||||
.apply("CONCAT (',',tree_path,',') LIKE CONCAT('%,',{0},',%')", id));
|
||||
boolean result = this.remove(new LambdaQueryWrapper<SysMenu>()
|
||||
.eq(SysMenu::getId, id)
|
||||
.or()
|
||||
.apply("CONCAT (',',tree_path,',') LIKE CONCAT('%,',{0},',%')", id));
|
||||
|
||||
|
||||
// 刷新角色权限缓存
|
||||
if (result) {
|
||||
permissionService.refreshRolePermsCache();
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,31 +2,33 @@ package com.youlai.system.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.system.common.constant.SystemConstants;
|
||||
import com.youlai.system.common.model.Option;
|
||||
import com.youlai.system.security.util.SecurityUtils;
|
||||
import com.youlai.system.converter.RoleConverter;
|
||||
import com.youlai.system.security.service.PermissionService;
|
||||
import com.youlai.system.mapper.SysRoleMapper;
|
||||
import com.youlai.system.model.entity.SysRole;
|
||||
import com.youlai.system.model.entity.SysRoleMenu;
|
||||
import com.youlai.system.model.form.RoleForm;
|
||||
import com.youlai.system.model.query.RolePageQuery;
|
||||
import com.youlai.system.model.vo.RolePageVO;
|
||||
import com.youlai.system.security.service.PermissionService;
|
||||
import com.youlai.system.service.SysRoleMenuService;
|
||||
import com.youlai.system.service.SysRoleService;
|
||||
import com.youlai.system.service.SysUserRoleService;
|
||||
import com.youlai.system.security.util.SecurityUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 角色业务实现类
|
||||
@@ -100,19 +102,37 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
public boolean saveRole(RoleForm roleForm) {
|
||||
|
||||
Long roleId = roleForm.getId();
|
||||
String roleCode = roleForm.getCode();
|
||||
|
||||
// 编辑角色时,判断角色是否存在
|
||||
SysRole oldRole = null;
|
||||
if (roleId != null) {
|
||||
oldRole = this.getById(roleId);
|
||||
Assert.isTrue(oldRole != null, "角色不存在");
|
||||
}
|
||||
|
||||
String roleCode = roleForm.getCode();
|
||||
long count = this.count(new LambdaQueryWrapper<SysRole>()
|
||||
.ne(roleId != null, SysRole::getId, roleId)
|
||||
.and(wrapper ->
|
||||
wrapper.eq(SysRole::getCode, roleCode).or().eq(SysRole::getName, roleForm.getName())
|
||||
));
|
||||
Assert.isTrue(count == 0, "角色名称或角色编码重复,请检查!");
|
||||
Assert.isTrue(count == 0, "角色名称或角色编码已存在,请修改后重试!");
|
||||
|
||||
// 实体转换
|
||||
SysRole role = roleConverter.form2Entity(roleForm);
|
||||
|
||||
return this.saveOrUpdate(role);
|
||||
boolean result = this.saveOrUpdate(role);
|
||||
if (result) {
|
||||
// 判断角色编码或状态是否修改,修改了则刷新权限缓存
|
||||
if (oldRole != null
|
||||
&& (
|
||||
!StrUtil.equals(oldRole.getCode(), roleCode) ||
|
||||
!ObjectUtil.equals(oldRole.getStatus(), roleForm.getStatus())
|
||||
)) {
|
||||
permissionService.refreshRolePermsCache(oldRole.getCode(), roleCode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,9 +156,16 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
*/
|
||||
@Override
|
||||
public boolean updateRoleStatus(Long roleId, Integer status) {
|
||||
return this.update(new LambdaUpdateWrapper<SysRole>()
|
||||
.eq(SysRole::getId, roleId)
|
||||
.set(SysRole::getStatus, status));
|
||||
|
||||
SysRole role = this.getById(roleId);
|
||||
Assert.isTrue(role != null, "角色不存在");
|
||||
|
||||
boolean result = this.updateById(role);
|
||||
if (result) {
|
||||
// 刷新角色的权限缓存
|
||||
permissionService.refreshRolePermsCache(role.getCode());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,9 +190,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
Assert.isTrue(!isRoleAssigned, "角色【{}】已分配用户,请先解除关联后删除", role.getName());
|
||||
|
||||
boolean deleteResult = this.removeById(roleId);
|
||||
if(deleteResult) {
|
||||
if (deleteResult) {
|
||||
// 删除成功,刷新权限缓存
|
||||
permissionService.refreshPermissionCache(role.getCode());
|
||||
permissionService.refreshRolePermsCache(role.getCode());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -193,8 +220,14 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
@Transactional
|
||||
@CacheEvict(cacheNames = "menu", key = "'routes'")
|
||||
public boolean assignMenusToRole(Long roleId, List<Long> menuIds) {
|
||||
SysRole role = this.getById(roleId);
|
||||
Assert.isTrue(role != null, "角色不存在");
|
||||
|
||||
// 删除角色菜单
|
||||
roleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
|
||||
roleMenuService.remove(
|
||||
new LambdaQueryWrapper<SysRoleMenu>()
|
||||
.eq(SysRoleMenu::getRoleId, roleId)
|
||||
);
|
||||
// 新增角色菜单
|
||||
if (CollectionUtil.isNotEmpty(menuIds)) {
|
||||
List<SysRoleMenu> roleMenus = menuIds
|
||||
@@ -203,6 +236,10 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
||||
.toList();
|
||||
roleMenuService.saveBatch(roleMenus);
|
||||
}
|
||||
|
||||
// 刷新角色的权限缓存
|
||||
permissionService.refreshRolePermsCache(role.getCode());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ import com.youlai.system.model.query.UserPageQuery;
|
||||
import com.youlai.system.model.vo.UserExportVO;
|
||||
import com.youlai.system.model.vo.UserInfoVO;
|
||||
import com.youlai.system.model.vo.UserPageVO;
|
||||
import com.youlai.system.security.service.PermissionService;
|
||||
import com.youlai.system.service.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -54,7 +54,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
private final SysRoleService roleService;
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
private final PermissionService permissionService;
|
||||
|
||||
/**
|
||||
* 获取用户分页列表
|
||||
@@ -254,7 +254,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||
|
||||
// 用户权限集合
|
||||
if (CollectionUtil.isNotEmpty(roles)) {
|
||||
Set<String> perms = menuService.listRolePerms(roles);
|
||||
Set<String> perms = permissionService.getRolePermsFormCache(roles);
|
||||
userInfoVO.setPerms(perms);
|
||||
}
|
||||
return userInfoVO;
|
||||
|
||||
Reference in New Issue
Block a user