SaTokenConfig.java 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package com.xjrsoft.config;
  2. import cn.dev33.satoken.context.SaHolder;
  3. import cn.dev33.satoken.exception.DisableServiceException;
  4. import cn.dev33.satoken.exception.NotLoginException;
  5. import cn.dev33.satoken.exception.NotPermissionException;
  6. import cn.dev33.satoken.exception.NotRoleException;
  7. import cn.dev33.satoken.filter.SaServletFilter;
  8. import cn.dev33.satoken.router.SaHttpMethod;
  9. import cn.dev33.satoken.router.SaRouter;
  10. import cn.dev33.satoken.stp.StpUtil;
  11. import cn.dev33.satoken.temp.SaTempUtil;
  12. import cn.dev33.satoken.util.SaResult;
  13. import cn.hutool.core.util.StrUtil;
  14. import com.xjrsoft.common.constant.GlobalConstant;
  15. import com.xjrsoft.common.enums.ResponseCode;
  16. import com.xjrsoft.common.exception.MyException;
  17. import com.xjrsoft.common.interceptor.MagicApiWebLoginInterceptor;
  18. import com.xjrsoft.common.interceptor.RateLimitInterceptor;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.context.annotation.Bean;
  21. import org.springframework.context.annotation.Configuration;
  22. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  23. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  24. /**
  25. * @Author: tzx
  26. * @Date: 2022/3/3 17:18
  27. */
  28. @Configuration
  29. public class SaTokenConfig implements WebMvcConfigurer {
  30. @Autowired
  31. private MagicApiConfig magicApiConfig;
  32. @Autowired
  33. private CommonPropertiesConfig commonPropertiesConfig;
  34. /**
  35. * 注册Sa-Token 的拦截器,打开注解式鉴权功能
  36. */
  37. @Override
  38. public void addInterceptors(InterceptorRegistry registry) {
  39. // 注册MagicApi登录判断拦截器
  40. registry.addInterceptor(new MagicApiWebLoginInterceptor()).addPathPatterns(magicApiConfig.getWeb() + "/**");
  41. // 注册拦截器
  42. registry.addInterceptor(getRateLimitInterceptor()).addPathPatterns("/**");
  43. //satoken 注解鉴权拦截器
  44. // registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
  45. }
  46. @Bean
  47. public RateLimitInterceptor getRateLimitInterceptor(){
  48. return new RateLimitInterceptor();
  49. }
  50. /**
  51. * 注册 [Sa-Token全局过滤器]
  52. */
  53. @Bean
  54. public SaServletFilter getSaServletFilter() {
  55. return new SaServletFilter()
  56. // 指定 拦截路由 与 放行路由
  57. .addInclude("/**")
  58. .addExclude(commonPropertiesConfig.getExcludeUrls().toArray(new String[0]))
  59. // 认证函数: 每次请求执行
  60. .setAuth(obj -> {
  61. // 登录认证 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
  62. if (commonPropertiesConfig.getWhiteList().contains(SaHolder.getRequest().getUrl())) {
  63. return;
  64. }
  65. String token = SaHolder.getRequest().getParam("token");
  66. if (StrUtil.isNotBlank(token)) {
  67. try {
  68. String tokenValue = SaTempUtil.parseToken(token, String.class);
  69. if (!tokenValue.contains(GlobalConstant.SECRET_KEY) || SaTempUtil.getTimeout(token) < 1) {
  70. throw new MyException("临时token 无效!");
  71. } else {
  72. return;
  73. }
  74. } catch (Exception e) {
  75. throw new MyException("临时token 无效!");
  76. }
  77. }
  78. SaRouter.match("/**", "/system/login", StpUtil::checkLogin);
  79. // 更多拦截处理方式,请参考“路由拦截式鉴权”章节
  80. })
  81. // 异常处理函数:每次认证函数发生异常时执行此函数
  82. .setError(e -> {
  83. if (e instanceof NotLoginException) { // 如果是未登录异常3
  84. return SaResult.get(ResponseCode.UN_AUTHORIZED.getCode(), ResponseCode.UN_AUTHORIZED.getMessage(), null);
  85. } else if (e instanceof NotRoleException) { // 如果是角色异常
  86. return SaResult.get(ResponseCode.REQ_REJECT.getCode(), ResponseCode.REQ_REJECT.getMessage(), null);
  87. } else if (e instanceof NotPermissionException) { // 如果是权限异常
  88. return SaResult.get(ResponseCode.REQ_REJECT.getCode(), ResponseCode.REQ_REJECT.getMessage(), null);
  89. } else if (e instanceof DisableServiceException) { // 如果是被封禁异常
  90. return SaResult.get(ResponseCode.REQ_REJECT.getCode(), ResponseCode.REQ_REJECT.getMessage(), null);
  91. } else { // 普通异常, 输出:500 + 异常信息
  92. return SaResult.get(ResponseCode.INTERNAL_SERVER_ERROR.getCode(), ResponseCode.INTERNAL_SERVER_ERROR.getMessage(), null);
  93. }
  94. })
  95. // 前置函数:在每次认证函数之前执行
  96. .setBeforeAuth(r -> {
  97. // ---------- 设置一些安全响应头 ----------
  98. SaHolder.getResponse()
  99. // 服务器名称
  100. .setServer("sa-server")
  101. // 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
  102. .setHeader("X-Frame-Options", "SAMEORIGIN")
  103. // 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
  104. .setHeader("X-XSS-Protection", "1; mode=block")
  105. // 禁用浏览器内容嗅探
  106. .setHeader("X-Content-Type-Options", "nosniff")
  107. // 域名
  108. .setHeader("Access-Control-Allow-Origin", "*")
  109. // 请求方式
  110. .setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT")
  111. // 缓存时间
  112. .setHeader("Access-Control-Max-Age", "3600")
  113. // 请求头
  114. .setHeader("Access-Control-Allow-Headers", "*");
  115. //option 必须跳过 不然会影响 cors配置 而且 必须放在设置请求头后面
  116. SaRouter.match(SaHttpMethod.OPTIONS).back();
  117. });
  118. }
  119. }