mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-11-12 21:53:48 +08:00
sa-token update
This commit is contained in:
@@ -3,10 +3,13 @@ package net.lab1024.sa.admin.config;
|
||||
import cn.dev33.satoken.interceptor.SaInterceptor;
|
||||
import cn.dev33.satoken.router.SaRouter;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import net.lab1024.sa.common.config.UrlConfig;
|
||||
import net.lab1024.sa.admin.module.system.menu.service.MenuCacheService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* sa-token 配置
|
||||
*
|
||||
@@ -16,6 +19,9 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration
|
||||
public class SaTokenConfig {
|
||||
|
||||
@Autowired
|
||||
private MenuCacheService menuService;
|
||||
|
||||
/**
|
||||
* 定义 Sa-Token 拦截器,定义详细认证规则
|
||||
*/
|
||||
@@ -23,12 +29,9 @@ public class SaTokenConfig {
|
||||
public SaInterceptor saInterceptor() {
|
||||
// 关闭注解鉴权 只做路由拦截校验
|
||||
return new SaInterceptor(handler -> {
|
||||
/**
|
||||
* 每个路由 都做为一个权限点
|
||||
* TODO listen from定义的api
|
||||
* from menu数据表已选择的api
|
||||
*/
|
||||
UrlConfig.AUTH_URL_LIST.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url)));
|
||||
// 查询数据表中 需要校验权限的url
|
||||
List<String> urlList = menuService.queryNeedCheckPermissionsUrl();
|
||||
urlList.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url)));
|
||||
}).isAnnotation(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
package net.lab1024.sa.admin.interceptor;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.convert.NumberWithFormat;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.lab1024.sa.common.common.domain.RequestUser;
|
||||
import net.lab1024.sa.common.common.enumeration.UserTypeEnum;
|
||||
import net.lab1024.sa.common.common.interceptor.AbstractInterceptor;
|
||||
import net.lab1024.sa.common.common.util.SmartEnumUtil;
|
||||
import net.lab1024.sa.common.module.support.token.TokenService;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -23,6 +19,24 @@ import java.util.List;
|
||||
@Configuration
|
||||
public class AdminInterceptor extends AbstractInterceptor {
|
||||
|
||||
/**
|
||||
* 此处可根据需要
|
||||
* 自行查询用户信息
|
||||
*/
|
||||
@Override
|
||||
public RequestUser getDevUser(Long userId) {
|
||||
RequestUser requestUser = new RequestUser();
|
||||
requestUser.setUserId(userId);
|
||||
requestUser.setUserName("dev");
|
||||
requestUser.setUserType(this.getUserType());
|
||||
return requestUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserTypeEnum getUserType() {
|
||||
return UserTypeEnum.ADMIN_EMPLOYEE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置拦截路径
|
||||
*
|
||||
@@ -33,27 +47,16 @@ public class AdminInterceptor extends AbstractInterceptor {
|
||||
return Lists.newArrayList("/**");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSaToken() {
|
||||
StpUtil.checkLogin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestUser getRequestUser() {
|
||||
// 获取额外数据
|
||||
Integer userType = ((NumberWithFormat) StpUtil.getExtra(TokenService.EXTRA_KEY_USER_TYPE)).intValue();
|
||||
UserTypeEnum userTypeEnum = SmartEnumUtil.getEnumByValue(userType, UserTypeEnum.class);
|
||||
String userName = (String) StpUtil.getExtra(TokenService.EXTRA_KEY_USER_NAME);
|
||||
String loginId = (String) StpUtil.getLoginId();
|
||||
|
||||
// 当前请求对象
|
||||
RequestUser requestUser = new RequestUser();
|
||||
requestUser.setUserId(TokenService.getUserId(loginId));
|
||||
requestUser.setUserName(userName);
|
||||
requestUser.setUserType(userTypeEnum);
|
||||
return requestUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果没有需要处理的业务
|
||||
* 那就没有必要重写了 可以删除这个方法
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param handler
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
boolean isHandle = super.preHandle(request, response, handler);
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
package net.lab1024.sa.admin.module.system.employee.service;
|
||||
|
||||
import cn.dev33.satoken.session.SaSession;
|
||||
import cn.dev33.satoken.session.SaSessionCustomUtil;
|
||||
import cn.dev33.satoken.stp.StpInterface;
|
||||
import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao;
|
||||
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum;
|
||||
import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity;
|
||||
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
|
||||
import net.lab1024.sa.admin.module.system.role.dao.RoleMenuDao;
|
||||
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
|
||||
import net.lab1024.sa.admin.module.system.role.service.RoleMenuService;
|
||||
import net.lab1024.sa.common.common.enumeration.UserTypeEnum;
|
||||
import net.lab1024.sa.common.module.support.token.TokenService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -33,7 +40,22 @@ public class EmployeePermissionService implements StpInterface {
|
||||
private RoleMenuService roleMenuService;
|
||||
|
||||
@Autowired
|
||||
private EmployeeDao employeeDao;
|
||||
private RoleMenuDao roleMenuDao;
|
||||
|
||||
/**
|
||||
* 员工关联权限 缓存key
|
||||
*/
|
||||
private static final String USER_ROLE_CACHE_KEY = "RoleList";
|
||||
|
||||
/**
|
||||
* 角色关联功能点 缓存key
|
||||
*/
|
||||
private static final String ROLE_CACHE_KEY = "role:";
|
||||
|
||||
/**
|
||||
* 角色关联功能点 缓存key
|
||||
*/
|
||||
private static final String ROLE_PERMISSION_CACHE_KEY = "PermissionList";
|
||||
|
||||
/**
|
||||
* 查询用户拥有的前端菜单项 用于登陆返回 前端动态路由配置
|
||||
@@ -48,18 +70,61 @@ public class EmployeePermissionService implements StpInterface {
|
||||
|
||||
@Override
|
||||
public List<String> getPermissionList(Object loginId, String loginType) {
|
||||
Long employeeId = TokenService.getUserId((String) loginId);
|
||||
// 权限集合
|
||||
List<String> permissionList = new ArrayList<>();
|
||||
|
||||
// TODO listen 待做权限缓存
|
||||
EmployeeEntity employeeEntity = employeeDao.selectById(employeeId);
|
||||
List<MenuVO> menuList = this.getEmployeeMenuAndPointsList(employeeId, employeeEntity.getAdministratorFlag());
|
||||
return menuList.stream()
|
||||
.filter(e -> MenuTypeEnum.POINTS.equalsValue(e.getMenuType()))
|
||||
.map(MenuVO::getApiPerms).distinct().collect(Collectors.toList());
|
||||
// 遍历角色列表,查询拥有的权限
|
||||
List<String> roleList = this.getRoleList(loginId, loginType);
|
||||
for (String roleId : roleList) {
|
||||
// 查询缓存
|
||||
SaSession roleSession = SaSessionCustomUtil.getSessionById(ROLE_CACHE_KEY + roleId);
|
||||
List<String> list = roleSession.get(ROLE_PERMISSION_CACHE_KEY, () -> {
|
||||
// 从数据库查询这个角色所拥有的权限列表
|
||||
return roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(Long.parseLong(roleId)), false)
|
||||
.stream()
|
||||
.filter(e -> MenuTypeEnum.POINTS.equalsValue(e.getMenuType()))
|
||||
.map(MenuEntity::getApiPerms).filter(Objects::nonNull).distinct()
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
permissionList.addAll(list);
|
||||
}
|
||||
// 返回权限集合
|
||||
return permissionList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleList(Object loginId, String loginType) {
|
||||
return null;
|
||||
SaSession session = StpUtil.getSessionByLoginId(loginId);
|
||||
// 查询员工关联角色缓存
|
||||
Long employeeId = TokenService.getUserId((String) loginId);
|
||||
return session.get(USER_ROLE_CACHE_KEY, () -> {
|
||||
// 数据库中查询员工角色
|
||||
return roleEmployeeService.getRoleIdList(employeeId).stream().map(String::valueOf).collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理角色关联权限 缓存
|
||||
* TODO listen 待调用
|
||||
*
|
||||
* @param roleId
|
||||
*/
|
||||
public static void clearRoleCache(Long roleId) {
|
||||
SaSessionCustomUtil.deleteSessionById(ROLE_CACHE_KEY + roleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 员工关联角色 缓存
|
||||
* TODO listen 待调用
|
||||
*
|
||||
* @param employeeId
|
||||
*/
|
||||
public static void clearUserRoleCache(Long employeeId) {
|
||||
String loginId = TokenService.generateLoginId(employeeId, UserTypeEnum.ADMIN_EMPLOYEE);
|
||||
SaSession session = StpUtil.getSessionByLoginId(loginId, false);
|
||||
if (null == session) {
|
||||
return;
|
||||
}
|
||||
session.delete(USER_ROLE_CACHE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class LoginController {
|
||||
return loginService.getCaptcha();
|
||||
}
|
||||
|
||||
// TODO listen
|
||||
// TODO listen 测试待删除
|
||||
@NoNeedLogin
|
||||
@ApiOperation("测试权限 @listen")
|
||||
@GetMapping("/listen/test")
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package net.lab1024.sa.admin.module.system.menu.constant;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.lab1024.sa.common.common.enumeration.BaseEnum;
|
||||
|
||||
/**
|
||||
@@ -12,6 +14,8 @@ import net.lab1024.sa.common.common.enumeration.BaseEnum;
|
||||
* @Email lab1024@163.com
|
||||
* @Copyright 1024创新实验室 ( https://1024lab.net )
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MenuTypeEnum implements BaseEnum {
|
||||
/**
|
||||
* 目录
|
||||
@@ -26,23 +30,7 @@ public enum MenuTypeEnum implements BaseEnum {
|
||||
*/
|
||||
POINTS(3, "功能点");
|
||||
|
||||
private Integer value;
|
||||
private final Integer value;
|
||||
|
||||
private String desc;
|
||||
|
||||
|
||||
MenuTypeEnum(Integer value, String desc) {
|
||||
this.value = value;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
private final String desc;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.lab1024.sa.admin.module.system.menu.service;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import lombok.SneakyThrows;
|
||||
import net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum;
|
||||
import net.lab1024.sa.admin.module.system.menu.dao.MenuDao;
|
||||
import net.lab1024.sa.admin.module.system.menu.domain.entity.MenuEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 功能菜单业务
|
||||
*
|
||||
* @author Turbolisten
|
||||
* @date 2023/7/20 19:04
|
||||
*/
|
||||
@Service
|
||||
public class MenuCacheService {
|
||||
|
||||
@Autowired
|
||||
private MenuDao menuDao;
|
||||
|
||||
private static final Cache<String, List<String>> MENU_URL_CACHE = CacheBuilder.newBuilder().build();
|
||||
|
||||
/**
|
||||
* 查询数据表中 需要校验权限的url
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public List<String> queryNeedCheckPermissionsUrl() {
|
||||
return MENU_URL_CACHE.get("MENU_URL_CACHE", () -> {
|
||||
// TODO listen 待确定哪个字段做为url
|
||||
return menuDao.queryMenuByType(MenuTypeEnum.POINTS.getValue(), false, false)
|
||||
.stream()
|
||||
.map(MenuEntity::getApiPerms)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
MENU_URL_CACHE.invalidateAll();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -65,6 +65,12 @@ public class MenuService {
|
||||
menuEntity.setApiPerms(perms);
|
||||
}
|
||||
menuDao.insert(menuEntity);
|
||||
|
||||
// 清除权限缓存
|
||||
if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) {
|
||||
MenuCacheService.clearCache();
|
||||
}
|
||||
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@@ -102,6 +108,11 @@ public class MenuService {
|
||||
menuEntity.setApiPerms(perms);
|
||||
}
|
||||
menuDao.updateById(menuEntity);
|
||||
|
||||
// 清除权限缓存
|
||||
if (MenuTypeEnum.POINTS.equalsValue(menuEntity.getMenuType())) {
|
||||
MenuCacheService.clearCache();
|
||||
}
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@@ -118,8 +129,11 @@ public class MenuService {
|
||||
return ResponseDTO.userErrorParam("所选菜单不能为空");
|
||||
}
|
||||
menuDao.deleteByMenuIdList(menuIdList, employeeId, Boolean.TRUE);
|
||||
//孩子节点也需要删除
|
||||
// 子节点也需要删除
|
||||
this.recursiveDeleteChildren(menuIdList, employeeId);
|
||||
|
||||
// 清除权限缓存
|
||||
MenuCacheService.clearCache();
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user