SaTokenConfigure.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package com.fdkankan.manage.config;
  2. import cn.dev33.satoken.context.SaHolder;
  3. import cn.dev33.satoken.filter.SaServletFilter;
  4. import cn.dev33.satoken.jwt.StpLogicJwtForMixin;
  5. import cn.dev33.satoken.router.SaRouter;
  6. import cn.dev33.satoken.stp.StpLogic;
  7. import cn.dev33.satoken.stp.StpUtil;
  8. import com.alibaba.fastjson.JSONArray;
  9. import com.alibaba.fastjson.JSONObject;
  10. import com.alibaba.nacos.common.utils.HttpMethod;
  11. import com.fdkankan.common.constant.ErrorCode;
  12. import com.fdkankan.common.exception.BusinessException;
  13. import com.fdkankan.common.response.ResultData;
  14. import com.fdkankan.redis.constant.RedisKey;
  15. import com.fdkankan.redis.util.RedisUtil;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.context.annotation.Bean;
  19. import org.springframework.context.annotation.Configuration;
  20. import java.util.HashMap;
  21. @Configuration
  22. public class SaTokenConfigure {
  23. public static HashMap<String, JSONObject> manageMenuUrl = new HashMap<>();
  24. public static HashMap<String, JSONObject> manageMenuId = new HashMap<>();
  25. @Autowired
  26. RedisUtil redisUtil;
  27. // 注册Sa-Token的拦截器
  28. @Bean
  29. public SaServletFilter getSaServletFilter() {
  30. return new SaServletFilter()
  31. // 指定 拦截路由 与 放行路由
  32. .addInclude("/**").addExclude("/favicon.ico")
  33. // 认证函数: 每次请求执行
  34. .setAuth(obj -> {
  35. System.out.println("---------- 进入Sa-Token全局认证 -----------");
  36. // 登录认证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
  37. SaRouter.match("/**", "/service/manage/login", r ->checkLogin() );
  38. String menu = redisUtil.get(RedisKey.MANAGE_MENU);
  39. if(StringUtils.isBlank(menu)){
  40. SaRouter.match("/**", r -> StpUtil.checkRole("super-admin"));
  41. }
  42. JSONArray menuArray = JSONObject.parseArray(menu);
  43. for (Object o : menuArray) {
  44. JSONObject jsonObject = (JSONObject) o;
  45. String url = jsonObject.getString("url");
  46. String perm = jsonObject.getString("perms");
  47. manageMenuId.put(jsonObject.getString("id"),jsonObject);
  48. if(StringUtils.isEmpty(url) || StringUtils.isEmpty(perm)){
  49. continue;
  50. }
  51. SaRouter.match(url, r -> StpUtil.checkPermission(perm));
  52. manageMenuUrl.put(jsonObject.getString("url"),jsonObject);
  53. }
  54. })
  55. // 异常处理函数:每次认证函数发生异常时执行此函数
  56. .setError(e -> {
  57. System.out.println("---------- 进入Sa-Token异常处理 -----------");
  58. SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
  59. return JSONObject.toJSONString(ResultData.error(-1,e.getMessage()));
  60. })
  61. // 前置函数:在每次认证函数之前执行
  62. .setBeforeAuth(r -> {
  63. // ---------- 设置一些安全响应头 ----------
  64. SaHolder.getResponse()
  65. .setHeader("Access-Control-Allow-Origin", "*")
  66. .setHeader("Access-Control-Allow-Methods", "*")
  67. .setHeader("Access-Control-Max-Age", "3600")
  68. .setHeader("Access-Control-Allow-Headers", "*")
  69. .setServer("4dkk");
  70. // 跳过对 OPTIONS 请求的检查,否则这里会鉴权失败,导致 springboot 配置的 addCorsMappings 跨域不执行
  71. if (SaHolder.getRequest().getMethod().equals(HttpMethod.OPTIONS.toString())) {
  72. SaRouter.back();
  73. }
  74. });
  75. }
  76. private void checkLogin(){
  77. if(!redisUtil.hasKey(String.format(RedisKey.TOKEN_V3,StpUtil.getTokenValue()))){
  78. throw new BusinessException(ErrorCode.USER_NOT_LOGIN);
  79. }
  80. redisUtil.expire(String.format(RedisKey.TOKEN_V3,StpUtil.getTokenValue()),21600);
  81. StpUtil.checkLogin();
  82. }
  83. // Sa-Token 整合 jwt
  84. //Stateless 无状态模式 纯jwt
  85. //Mixin 混入模式 jwt 与 Redis 逻辑混合
  86. //Simple 简单模式 Token风格替换
  87. @Bean
  88. public StpLogic getStpLogicJwt() {
  89. return new StpLogicJwtForMixin();
  90. }
  91. }