mirror of
				https://gitee.com/lab1024/smart-admin.git
				synced 2025-11-04 10:23:43 +08:00 
			
		
		
		
	sa-token
This commit is contained in:
		@@ -4,13 +4,8 @@ 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 org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.DependsOn;
 | 
			
		||||
import org.springframework.context.annotation.Lazy;
 | 
			
		||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 | 
			
		||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 | 
			
		||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * sa-token 配置
 | 
			
		||||
@@ -19,25 +14,21 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
 | 
			
		||||
 * @date 2023/7/13 16:57
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
public class SaTokenConfig implements WebMvcConfigurer {
 | 
			
		||||
public class SaTokenConfig {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册 Sa-Token 拦截器,定义详细认证规则
 | 
			
		||||
     *
 | 
			
		||||
     * @param registry
 | 
			
		||||
     * 定义 Sa-Token 拦截器,定义详细认证规则
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addInterceptors(InterceptorRegistry registry) {
 | 
			
		||||
        SaInterceptor interceptor = new SaInterceptor(handler -> {
 | 
			
		||||
 | 
			
		||||
            // 每个路由 都做为一个权限点
 | 
			
		||||
            UrlConfig.URL_LIST.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url)));
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    @Bean
 | 
			
		||||
    public SaInterceptor saInterceptor() {
 | 
			
		||||
        // 关闭注解鉴权 只做路由拦截校验
 | 
			
		||||
        interceptor.isAnnotation(false);
 | 
			
		||||
        registry.addInterceptor(interceptor).addPathPatterns("/**");
 | 
			
		||||
        return new SaInterceptor(handler -> {
 | 
			
		||||
            /**
 | 
			
		||||
             * 每个路由 都做为一个权限点
 | 
			
		||||
             * TODO listen from定义的api
 | 
			
		||||
             *             from menu数据表已选择的api
 | 
			
		||||
             */
 | 
			
		||||
            UrlConfig.AUTH_URL_LIST.forEach(url -> SaRouter.match(url, r -> StpUtil.checkPermission(url)));
 | 
			
		||||
        }).isAnnotation(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,18 @@
 | 
			
		||||
package net.lab1024.sa.admin.module.system.employee.service;
 | 
			
		||||
 | 
			
		||||
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 net.lab1024.sa.admin.module.system.menu.constant.MenuTypeEnum;
 | 
			
		||||
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
 | 
			
		||||
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.module.support.token.TokenService;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 员工权限校验
 | 
			
		||||
@@ -18,7 +24,7 @@ import java.util.List;
 | 
			
		||||
 * @Copyright 1024创新实验室 ( https://1024lab.net )
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
public class EmployeePermissionService {
 | 
			
		||||
public class EmployeePermissionService implements StpInterface {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private RoleEmployeeService roleEmployeeService;
 | 
			
		||||
@@ -26,6 +32,9 @@ public class EmployeePermissionService {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private RoleMenuService roleMenuService;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private EmployeeDao employeeDao;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询用户拥有的前端菜单项 用于登陆返回 前端动态路由配置
 | 
			
		||||
     *
 | 
			
		||||
@@ -37,4 +46,20 @@ public class EmployeePermissionService {
 | 
			
		||||
        return roleMenuService.getMenuList(roleIdList, administratorFlag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> getPermissionList(Object loginId, String loginType) {
 | 
			
		||||
        Long employeeId = TokenService.getUserId((String) loginId);
 | 
			
		||||
 | 
			
		||||
        // 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());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<String> getRoleList(Object loginId, String loginType) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package net.lab1024.sa.admin.module.system.login.controller;
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.annotation.SaIgnore;
 | 
			
		||||
import cn.hutool.extra.servlet.ServletUtil;
 | 
			
		||||
import io.swagger.annotations.Api;
 | 
			
		||||
import io.swagger.annotations.ApiOperation;
 | 
			
		||||
@@ -13,7 +12,6 @@ import net.lab1024.sa.common.common.constant.RequestHeaderConst;
 | 
			
		||||
import net.lab1024.sa.common.common.domain.ResponseDTO;
 | 
			
		||||
import net.lab1024.sa.common.common.util.SmartRequestUtil;
 | 
			
		||||
import net.lab1024.sa.common.module.support.captcha.domain.CaptchaVO;
 | 
			
		||||
import org.checkerframework.checker.units.qual.N;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.web.bind.annotation.GetMapping;
 | 
			
		||||
import org.springframework.web.bind.annotation.PostMapping;
 | 
			
		||||
@@ -58,20 +56,8 @@ public class LoginController {
 | 
			
		||||
    @ApiOperation("获取登录结果信息  @author 卓大")
 | 
			
		||||
    @GetMapping("/login/getLoginInfo")
 | 
			
		||||
    public ResponseDTO<LoginEmployeeDetail> getLoginInfo() {
 | 
			
		||||
       /* Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
 | 
			
		||||
        if (authentication == null) {
 | 
			
		||||
            return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Object principal = authentication.getPrincipal();
 | 
			
		||||
        if (!(principal instanceof LoginEmployeeDetail)) {
 | 
			
		||||
            return ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal();
 | 
			
		||||
        loginEmployeeDetail.setLoginPassword(null);
 | 
			
		||||
        return ResponseDTO.ok(loginEmployeeDetail);*/
 | 
			
		||||
        return ResponseDTO.ok();
 | 
			
		||||
        LoginEmployeeDetail loginEmployeeDetail = loginService.getLoginUserDetailCache(SmartRequestUtil.getUserId());
 | 
			
		||||
        return ResponseDTO.ok(loginEmployeeDetail);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @ApiOperation("退出登录  @author 卓大")
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@ public class LoginService {
 | 
			
		||||
        // 校验 图形验证码
 | 
			
		||||
        ResponseDTO<String> checkCaptcha = captchaService.checkCaptcha(loginForm);
 | 
			
		||||
        if (!checkCaptcha.getOk()) {
 | 
			
		||||
           // TODO listen 待放开 return ResponseDTO.error(checkCaptcha);
 | 
			
		||||
            // TODO listen 待放开 return ResponseDTO.error(checkCaptcha);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -160,7 +160,7 @@ public class LoginService {
 | 
			
		||||
        List<MenuVO> menuAndPointsList = employeePermissionService.getEmployeeMenuAndPointsList(employeeEntity.getEmployeeId(), employeeEntity.getAdministratorFlag());
 | 
			
		||||
        //前端菜单
 | 
			
		||||
        loginEmployeeDetail.setMenuList(menuAndPointsList);
 | 
			
		||||
        //后端权限
 | 
			
		||||
        // TODO listen 原先为什么返回权限
 | 
			
		||||
        // loginEmployeeDetail.setAuthorities(employeePermissionService.buildAuthorities(menuAndPointsList));
 | 
			
		||||
 | 
			
		||||
        //上次登录信息
 | 
			
		||||
@@ -195,6 +195,15 @@ public class LoginService {
 | 
			
		||||
        loginLogService.log(loginEntity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 查询用户信息缓存
 | 
			
		||||
     *
 | 
			
		||||
     * @param requestUserId
 | 
			
		||||
     */
 | 
			
		||||
    public LoginEmployeeDetail getLoginUserDetailCache(Long requestUserId) {
 | 
			
		||||
        return loginUserDetailCache.get(requestUserId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 移除用户信息缓存
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.util.CollectionUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
@@ -39,6 +38,10 @@ public class MenuService {
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private MenuDao menuDao;
 | 
			
		||||
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private List<RequestUrlVO> authUrl;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 添加菜单
 | 
			
		||||
     *
 | 
			
		||||
@@ -281,8 +284,7 @@ public class MenuService {
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public ResponseDTO<List<RequestUrlVO>> getAuthUrl() {
 | 
			
		||||
        // TODO listen
 | 
			
		||||
        return ResponseDTO.ok(Collections.emptyList());
 | 
			
		||||
        return ResponseDTO.ok(authUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -77,9 +77,9 @@ public class RoleMenuService {
 | 
			
		||||
     * @param roleIdList
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public List<MenuVO> getMenuList(List<Long> roleIdList, Boolean administratorFlag) {
 | 
			
		||||
        //管理员返回所有菜单
 | 
			
		||||
        if(administratorFlag){
 | 
			
		||||
    public List<MenuVO> getMenuList(List<Long> roleIdList, Boolean adminFlag) {
 | 
			
		||||
        // 超管返回所有菜单
 | 
			
		||||
        if(adminFlag){
 | 
			
		||||
            List<MenuEntity> menuEntityList = roleMenuDao.selectMenuListByRoleIdList(Lists.newArrayList(), false);
 | 
			
		||||
            return SmartBeanUtil.copyList(menuEntityList, MenuVO.class);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@ import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 抽象拦截器
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package net.lab1024.sa.common.config;
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.interceptor.SaInterceptor;
 | 
			
		||||
import net.lab1024.sa.common.common.interceptor.AbstractInterceptor;
 | 
			
		||||
import org.apache.commons.collections4.CollectionUtils;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
@@ -26,14 +27,24 @@ public class MvcConfig implements WebMvcConfigurer {
 | 
			
		||||
    @Autowired(required = false)
 | 
			
		||||
    private List<AbstractInterceptor> interceptorList;
 | 
			
		||||
 | 
			
		||||
    @Autowired(required = false)
 | 
			
		||||
    private List<SaInterceptor> saInterceptorList;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addInterceptors(InterceptorRegistry registry) {
 | 
			
		||||
        if (CollectionUtils.isEmpty(interceptorList)) {
 | 
			
		||||
            return;
 | 
			
		||||
        // 先注册 登录拦截器
 | 
			
		||||
        if (CollectionUtils.isNotEmpty(interceptorList)) {
 | 
			
		||||
            interceptorList.forEach(e -> {
 | 
			
		||||
                registry.addInterceptor(e).addPathPatterns(e.pathPatterns()).excludePathPatterns(e.getIgnoreUrlList());
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 后注册 sa-token 权限拦截器 不需要可以删除
 | 
			
		||||
        if (CollectionUtils.isNotEmpty(saInterceptorList)) {
 | 
			
		||||
            saInterceptorList.forEach(i -> {
 | 
			
		||||
                registry.addInterceptor(i).addPathPatterns("/**");
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        interceptorList.forEach(e -> {
 | 
			
		||||
            registry.addInterceptor(e).addPathPatterns(e.pathPatterns()).excludePathPatterns(e.getIgnoreUrlList());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ public class UrlConfig {
 | 
			
		||||
    @Autowired
 | 
			
		||||
    private RequestMappingHandlerMapping requestMappingHandlerMapping;
 | 
			
		||||
 | 
			
		||||
    public static List<String> URL_LIST = Lists.newArrayList();
 | 
			
		||||
    public static List<String> AUTH_URL_LIST = Lists.newArrayList();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取每个方法的请求路径
 | 
			
		||||
@@ -74,8 +74,15 @@ public class UrlConfig {
 | 
			
		||||
            if (null != ignore) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            List<RequestUrlVO> requestUrlList = this.buildRequestUrl(method, entry.getValue());
 | 
			
		||||
            NoNeedLogin noNeedLogin = method.getAnnotation(NoNeedLogin.class);
 | 
			
		||||
            if (null != noNeedLogin) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            Set<String> urlSet = entry.getValue();
 | 
			
		||||
            List<RequestUrlVO> requestUrlList = this.buildRequestUrl(method, urlSet);
 | 
			
		||||
            authUrlList.addAll(requestUrlList);
 | 
			
		||||
 | 
			
		||||
            AUTH_URL_LIST.addAll(urlSet);
 | 
			
		||||
        }
 | 
			
		||||
        log.info("需要权限校验的URL:{}", authUrlList.stream().map(RequestUrlVO::getUrl).collect(Collectors.toList()));
 | 
			
		||||
        return authUrlList;
 | 
			
		||||
@@ -98,8 +105,6 @@ public class UrlConfig {
 | 
			
		||||
            requestUrlVO.setUrl(url);
 | 
			
		||||
            requestUrlVO.setComment(methodComment);
 | 
			
		||||
            requestUrlList.add(requestUrlVO);
 | 
			
		||||
 | 
			
		||||
            URL_LIST.add(url);
 | 
			
		||||
        }
 | 
			
		||||
        return requestUrlList;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,10 @@ import org.springframework.stereotype.Component;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 与用户token的相关的服务
 | 
			
		||||
 * 用户token 相关服务
 | 
			
		||||
 *
 | 
			
		||||
 * @Author 1024创新实验室-主任: 卓大
 | 
			
		||||
 * @Date 2021-11-29 19:48:35
 | 
			
		||||
 * @Wechat zhuoda1024
 | 
			
		||||
 * @Email lab1024@163.com
 | 
			
		||||
 * @Copyright 1024创新实验室 ( https://1024lab.net )
 | 
			
		||||
 * @author listen
 | 
			
		||||
 * @date 2023-07-12 22:48:35
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
public class TokenService {
 | 
			
		||||
@@ -63,6 +60,10 @@ public class TokenService {
 | 
			
		||||
        return Long.valueOf(loginId.substring(loginId.indexOf(StringConst.HORIZONTAL) + 1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Integer getUserType(String loginId) {
 | 
			
		||||
        return Integer.valueOf(loginId.substring(0, loginId.indexOf(StringConst.HORIZONTAL)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 退出登录 注销
 | 
			
		||||
     */
 | 
			
		||||
 
 | 
			
		||||
@@ -131,12 +131,20 @@ sa-token:
 | 
			
		||||
  # token 有效期(单位:秒) 默认30天,-1 代表永久有效
 | 
			
		||||
  timeout: 2592000
 | 
			
		||||
  # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
 | 
			
		||||
  active-timeout: 28800
 | 
			
		||||
  active-timeout: -1
 | 
			
		||||
  # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
 | 
			
		||||
  is-concurrent: false
 | 
			
		||||
  # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)(jwt模式下恒false)
 | 
			
		||||
  is-share: false
 | 
			
		||||
  # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)(jwt模式下无用)
 | 
			
		||||
  token-style: simple-uuid
 | 
			
		||||
  # 是否打开自动续签 (如果此值为true,框架会在每次直接或间接调用 getLoginId() 时进行一次过期检查与续签操作)
 | 
			
		||||
  auto-renew: true
 | 
			
		||||
  # 是否输出操作日志
 | 
			
		||||
  is-log: true
 | 
			
		||||
  is-log: true
 | 
			
		||||
  # 日志等级(trace、debug、info、warn、error、fatal)
 | 
			
		||||
  log-level: debug
 | 
			
		||||
  # 启动时的字符画打印
 | 
			
		||||
  is-print: false
 | 
			
		||||
  # 是否从cookie读取token
 | 
			
		||||
  is-read-cookie: false
 | 
			
		||||
		Reference in New Issue
	
	Block a user