110 lines
4.7 KiB
Java
110 lines
4.7 KiB
Java
package com.isu.gaswellwatch.config;
|
||
|
||
|
||
import cn.dev33.satoken.context.SaHolder;
|
||
import cn.dev33.satoken.exception.NotLoginException;
|
||
import cn.dev33.satoken.filter.SaServletFilter;
|
||
import cn.dev33.satoken.router.SaRouter;
|
||
import cn.dev33.satoken.stp.StpUtil;
|
||
import cn.dev33.satoken.util.SaResult;
|
||
import cn.hutool.core.collection.CollectionUtil;
|
||
import com.isu.gaswellwatch.constants.UserConstant;
|
||
import com.isu.gaswellwatch.exception.BusinessException;
|
||
import com.isu.gaswellwatch.service.UserService;
|
||
import com.isu.gaswellwatch.vo.MenuVO;
|
||
import com.isu.gaswellwatch.vo.UserLoginInfoVO;
|
||
import jakarta.annotation.Resource;
|
||
import org.apache.commons.lang3.StringUtils;
|
||
import org.springframework.context.annotation.Bean;
|
||
import org.springframework.context.annotation.Configuration;
|
||
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
@Configuration
|
||
public class SaTokenConfigure {
|
||
|
||
@Resource
|
||
private InterfacePermissionSettings settings;
|
||
@Resource
|
||
private UserService userService;
|
||
|
||
// 注册 Sa-Token全局过滤器
|
||
@Bean
|
||
public SaServletFilter getSaServletFilter() {
|
||
return new SaServletFilter()
|
||
// 拦截地址 拦截全部path
|
||
.addInclude("/**")
|
||
// 开放地址
|
||
.addExclude("/favicon.ico")
|
||
// 鉴权方法:每次访问进入
|
||
.setAuth(obj -> {
|
||
// 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
|
||
SaRouter.match("/**")
|
||
.notMatch("/user/doLogin", "/user/file/files")
|
||
.check(r -> {
|
||
StpUtil.checkLogin();
|
||
this.checkPermission();
|
||
});
|
||
})
|
||
// 异常处理方法:每次setAuth函数出现异常时进入
|
||
.setError(e -> {
|
||
if (e instanceof NotLoginException) {
|
||
return SaResult.error(UserConstant.NOT_LOGIN_MSG).setCode(UserConstant.NOT_LOGIN_CODE);
|
||
}
|
||
return SaResult.error(e.getMessage());
|
||
})
|
||
|
||
// 前置函数:在每次认证函数之前执行(BeforeAuth 不受 includeList 与 excludeList 的限制,所有请求都会进入)
|
||
.setBeforeAuth(obj -> {
|
||
// ---------- 设置跨域响应头 ----------
|
||
SaHolder.getResponse()
|
||
// 允许指定域访问跨域资源
|
||
.setHeader("Access-Control-Allow-Origin", "*")
|
||
// 允许所有请求方式
|
||
.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
|
||
// 有效时间
|
||
.setHeader("Access-Control-Max-Age", "3600")
|
||
// 允许的header参数
|
||
.setHeader("Access-Control-Allow-Headers", "*");
|
||
|
||
});
|
||
}
|
||
|
||
|
||
private void checkPermission() {
|
||
//先判断接口是否为限制接口
|
||
HashMap<String, List<String>> identifier = this.settings.getIdentifier();
|
||
String res = "";
|
||
String requestPath = SaHolder.getRequest().getRequestPath();
|
||
if (identifier == null) return;
|
||
for (Map.Entry<String, List<String>> entry : identifier.entrySet()) {
|
||
if (entry.getValue().contains(requestPath)) {
|
||
res = entry.getKey();
|
||
}
|
||
}
|
||
//是限制接口才校验,不是直接放行
|
||
if (StringUtils.isNotBlank(res)) {
|
||
//获取token对应的菜单列表
|
||
UserLoginInfoVO userLoginInfoVO = (UserLoginInfoVO) StpUtil.getTokenSession().get(UserConstant.TOKEN_SESSION);
|
||
List<MenuVO> menuList = this.userService.getMenuList(userLoginInfoVO.getUserVO().getUsername());
|
||
if (CollectionUtil.isEmpty(menuList)) throw new BusinessException("未获取到用户菜单");
|
||
//判断菜单和标识是否合法
|
||
String menuId = SaHolder.getRequest().getHeader(UserConstant.HEADER_MENU_ID);
|
||
if (StringUtils.isBlank(menuId)) throw new BusinessException("未获取到请求发出所在菜单");
|
||
boolean flag = false;
|
||
for (MenuVO menuVO : menuList) {
|
||
if (menuId.equals(menuVO.getId().toString())) {
|
||
if (res.equals(menuVO.getIdentifier())) {
|
||
flag = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (!flag) throw new BusinessException("该用户没有接口" + requestPath + "的权限");
|
||
}
|
||
}
|
||
}
|
||
|