SaTokenConfigure.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package com.fdkankan.fusion.config;
  2. import cn.dev33.satoken.context.SaHolder;
  3. import cn.dev33.satoken.exception.NotLoginException;
  4. import cn.dev33.satoken.exception.NotPermissionException;
  5. import cn.dev33.satoken.exception.NotRoleException;
  6. import cn.dev33.satoken.filter.SaServletFilter;
  7. import cn.dev33.satoken.jwt.StpLogicJwtForMixin;
  8. import cn.dev33.satoken.router.SaRouter;
  9. import cn.dev33.satoken.stp.StpLogic;
  10. import cn.dev33.satoken.stp.StpUtil;
  11. import com.alibaba.fastjson.JSONArray;
  12. import com.alibaba.fastjson.JSONObject;
  13. import com.aliyun.oss.HttpMethod;
  14. import com.fdkankan.fusion.common.ResultCode;
  15. import com.fdkankan.fusion.common.ResultData;
  16. import com.fdkankan.fusion.common.util.RedisKeyUtil;
  17. import com.fdkankan.fusion.controller.LoginController;
  18. import com.fdkankan.fusion.exception.BusinessException;
  19. import com.fdkankan.fusion.httpClient.FdService;
  20. import com.fdkankan.fusion.httpClient.response.FdkkLoginVo;
  21. import com.fdkankan.fusion.response.ManageLoginResponse;
  22. import com.fdkankan.fusion.service.ITmPermissionService;
  23. import com.fdkankan.fusion.service.ITmUserService;
  24. import com.fdkankan.redis.constant.RedisKey;
  25. import com.fdkankan.redis.util.RedisUtil;
  26. import lombok.extern.slf4j.Slf4j;
  27. import org.apache.commons.lang3.StringUtils;
  28. import org.springframework.beans.factory.annotation.Autowired;
  29. import org.springframework.context.annotation.Bean;
  30. import org.springframework.context.annotation.Configuration;
  31. import java.util.HashMap;
  32. @Configuration
  33. @Slf4j
  34. public class SaTokenConfigure {
  35. @Autowired
  36. RedisUtil redisUtil;
  37. @Autowired
  38. FdService fdService;
  39. // 注册Sa-Token的拦截器
  40. @Bean
  41. public SaServletFilter getSaServletFilter() {
  42. return new SaServletFilter()
  43. // 指定 拦截路由 与 放行路由
  44. .addInclude("/**").addExclude("/**/test/**","/**/inner/**","/**/notAuth/**","/**/systemSetting/**","/**/downMD5/**","/**/downDocx/**","/**ws/**")
  45. // 认证函数: 每次请求执行
  46. .setAuth(obj -> {
  47. String share = SaHolder.getRequest().getHeader("share");
  48. if(StringUtils.isNotBlank(share) && "1".equals(share)){ //分享请求头
  49. return;
  50. }
  51. SaRouter.match("/sceneDownLog/list", r -> StpUtil.checkRoleOr("admin-super","admin-system","admin") );
  52. // 登录认证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
  53. SaRouter.match("/**", "/fdLogin", r ->checkLogin() );
  54. String menu = redisUtil.get(RedisKey.MANAGE_MENU);
  55. if(StringUtils.isBlank(menu)){
  56. SaRouter.match("/**", r -> StpUtil.checkRole("admin-super"));
  57. return;
  58. }
  59. JSONArray menuArray = JSONObject.parseArray(menu);
  60. for (Object o : menuArray) {
  61. JSONObject jsonObject = (JSONObject) o;
  62. String url = jsonObject.getString("url");
  63. String perm = jsonObject.getString("perms");
  64. if(StringUtils.isEmpty(url) || StringUtils.isEmpty(perm)){
  65. continue;
  66. }
  67. if(StpUtil.hasRole("admin-super")){
  68. continue;
  69. }
  70. SaRouter.match(url, r -> StpUtil.checkPermission(perm));
  71. }
  72. })
  73. // 异常处理函数:每次认证函数发生异常时执行此函数
  74. .setError(e -> {
  75. SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
  76. ResultData aj ;
  77. if (e instanceof NotLoginException) { // 如果是未登录异常
  78. NotLoginException ee = (NotLoginException) e;
  79. aj = ResultData.error(ResultCode.USER_NOT_LOGIN);
  80. }
  81. else if(e instanceof NotRoleException) { // 如果是角色异常
  82. NotRoleException ee = (NotRoleException) e;
  83. aj = ResultData.error(ResultCode.NOT_PERMISSION);
  84. }
  85. else if(e instanceof NotPermissionException) { // 如果是权限异常
  86. NotPermissionException ee = (NotPermissionException) e;
  87. aj = ResultData.error(ResultCode.NOT_PERMISSION);
  88. }
  89. else if(e instanceof BusinessException) { // 如果是权限异常
  90. BusinessException ee = (BusinessException) e;
  91. aj = ResultData.error(ee.getCode(),ee.getMessage());
  92. }
  93. else { // 普通异常, 输出:500 + 异常信息
  94. aj = ResultData.error(ResultCode.SYSTEM_ERROR);
  95. }
  96. return JSONObject.toJSONString(aj);
  97. })
  98. // 前置函数:在每次认证函数之前执行
  99. .setBeforeAuth(r -> {
  100. // ---------- 设置一些安全响应头 ----------
  101. SaHolder.getResponse()
  102. .setHeader("Access-Control-Allow-Origin", "*")
  103. .setHeader("Access-Control-Allow-Methods", "*")
  104. .setHeader("Access-Control-Max-Age", "3600")
  105. .setHeader("Access-Control-Allow-Headers", "*")
  106. .setServer("4dkk");
  107. // 跳过对 OPTIONS 请求的检查,否则这里会鉴权失败,导致 springboot 配置的 addCorsMappings 跨域不执行
  108. if (SaHolder.getRequest().getMethod().equals(HttpMethod.OPTIONS.toString())) {
  109. SaRouter.back();
  110. }
  111. });
  112. }
  113. private void checkLogin(){
  114. String redisKey = String.format(RedisKeyUtil.loginToken,StpUtil.getTokenValue());
  115. if(!redisUtil.hasKey(redisKey)){
  116. throw new BusinessException(ResultCode.USER_NOT_LOGIN);
  117. }
  118. String userStr = redisUtil.get(redisKey);
  119. ManageLoginResponse result = JSONObject.parseObject(userStr,ManageLoginResponse.class);
  120. Long userId = result.getUserId();
  121. if(userId == null || result.getStatus() == 0){
  122. String redisKey2 = String.format(RedisKeyUtil.loginUserName,result.getUserName());
  123. redisUtil.del(redisKey);
  124. redisUtil.del(redisKey2);
  125. throw new BusinessException(ResultCode.USERNAME_ERROR);
  126. }
  127. redisUtil.expire(redisKey,2 * 60 * 60);
  128. }
  129. //Sa-Token 整合 jwt
  130. //Stateless 无状态模式 纯jwt
  131. //Mixin 混入模式 jwt 与 Redis 逻辑混合
  132. //Simple 简单模式 Token风格替换
  133. @Bean
  134. public StpLogic getStpLogicJwt() {
  135. return new StpLogicJwtForMixin();
  136. }
  137. }