This commit is contained in:
		
							parent
							
								
									e3aa1b0fd0
								
							
						
					
					
						commit
						de5d9ea54c
					
				| 
						 | 
				
			
			@ -2,6 +2,7 @@ package com.recovery.admin.boot.config;
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
import com.recovery.admin.boot.interceptor.JwtInterceptor;
 | 
			
		||||
import com.recovery.common.base.config.redis.RedisCache;
 | 
			
		||||
import com.recovery.common.base.util.RedisUtil;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 | 
			
		||||
| 
						 | 
				
			
			@ -13,17 +14,16 @@ import javax.annotation.Resource;
 | 
			
		|||
@Configuration
 | 
			
		||||
public class InterceptConfig implements WebMvcConfigurer {
 | 
			
		||||
    @Resource
 | 
			
		||||
    RedisUtil redisUtil;
 | 
			
		||||
    RedisCache redisCache;
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addInterceptors(InterceptorRegistry registry) {
 | 
			
		||||
        //添加拦截器
 | 
			
		||||
        registry.addInterceptor(new JwtInterceptor(redisUtil))
 | 
			
		||||
        registry.addInterceptor(new JwtInterceptor(redisCache))
 | 
			
		||||
                //拦截的路径 需要进行token验证的路径
 | 
			
		||||
                .addPathPatterns("/**")
 | 
			
		||||
                //放行的路径
 | 
			
		||||
                .excludePathPatterns("/api/rest/users/getUserByUsername")
 | 
			
		||||
                .excludePathPatterns("/api/user/sendMsg")
 | 
			
		||||
                .excludePathPatterns("/api/user/loginPhone")
 | 
			
		||||
                //放行swagger 测试验证
 | 
			
		||||
                .excludePathPatterns("/api/user/get");
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
package com.recovery.admin.boot.controller;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.stp.StpUtil;
 | 
			
		||||
import com.recovery.admin.boot.service.ISysUserService;
 | 
			
		||||
import com.recovery.common.base.constant.Constants;
 | 
			
		||||
import com.recovery.common.base.dto.UserAuthDTO;
 | 
			
		||||
import com.recovery.common.base.result.ApiResult;
 | 
			
		||||
import com.recovery.common.base.util.HspHostUtil;
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +35,21 @@ public class testController {
 | 
			
		|||
    public ApiResult<UserAuthDTO> cs(@RequestParam String name, HttpServletRequest request) {
 | 
			
		||||
        UserAuthDTO authDTO = iSysUserService.getByUsername(name);
 | 
			
		||||
        log.info("测试库:"+authDTO.getStatus());
 | 
			
		||||
        log.info(redisUtil.get("123").toString());
 | 
			
		||||
        String user = StpUtil.getLoginIdDefaultNull()+"";
 | 
			
		||||
        StpUtil.kickoutByTokenValue(Constants.LOGIN_USRE_TOKEN);
 | 
			
		||||
//        StpUtil.logout();
 | 
			
		||||
        return ApiResult.ok(authDTO);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * cs
 | 
			
		||||
     */
 | 
			
		||||
    @GetMapping("/cs1")
 | 
			
		||||
    public ApiResult ccss(HttpServletRequest request) {
 | 
			
		||||
        String user = StpUtil.getLoginIdDefaultNull()+"";
 | 
			
		||||
        StpUtil.kickout(StpUtil.getLoginId());
 | 
			
		||||
//        StpUtil.logout();
 | 
			
		||||
        return ApiResult.ok("踢下线");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
package com.recovery.admin.boot.exception;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.exception.NotLoginException;
 | 
			
		||||
import cn.dev33.satoken.util.SaResult;
 | 
			
		||||
import com.recovery.common.base.result.ApiResult;
 | 
			
		||||
import com.recovery.common.base.result.ResultCode;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +30,45 @@ public class GlobalExceptionHandler {
 | 
			
		|||
        return ApiResult.failed(ResultCode.SYSTEM_EXECUTION_ERROR.getCode(), e.getMessage());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 全局异常拦截(拦截项目中的NotLoginException异常)
 | 
			
		||||
    @ExceptionHandler(NotLoginException.class)
 | 
			
		||||
    public ApiResult handlerNotLoginException(NotLoginException nle)
 | 
			
		||||
            throws Exception {
 | 
			
		||||
 | 
			
		||||
        // 打印堆栈,以供调试
 | 
			
		||||
        nle.printStackTrace();
 | 
			
		||||
 | 
			
		||||
        // 判断场景值,定制化异常信息
 | 
			
		||||
        String message = "";
 | 
			
		||||
        if(nle.getType().equals(NotLoginException.NOT_TOKEN)) {
 | 
			
		||||
            message = "未能读取到有效 token";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.INVALID_TOKEN)) {
 | 
			
		||||
            message = "token 无效";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.TOKEN_TIMEOUT)) {
 | 
			
		||||
            message = "token 已过期";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.BE_REPLACED)) {
 | 
			
		||||
            message = "token 已被顶下线";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.KICK_OUT)) {
 | 
			
		||||
            message = "token 已被踢下线";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.TOKEN_FREEZE)) {
 | 
			
		||||
            message = "token 已被冻结";
 | 
			
		||||
        }
 | 
			
		||||
        else if(nle.getType().equals(NotLoginException.NO_PREFIX)) {
 | 
			
		||||
            message = "未按照指定前缀提交 token";
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            message = "当前会话未登录";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 返回给前端
 | 
			
		||||
        return ApiResult.failed(message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Security
 | 
			
		||||
//    @ExceptionHandler(value = AccessDeniedException.class)
 | 
			
		||||
//    public void accessDeniedException(AccessDeniedException e) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,13 @@
 | 
			
		|||
package com.recovery.admin.boot.interceptor;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.stp.StpUtil;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.auth0.jwt.interfaces.DecodedJWT;
 | 
			
		||||
 | 
			
		||||
import com.recovery.admin.boot.exception.BusinessException;
 | 
			
		||||
import com.recovery.admin.boot.filter.RequestWrapper;
 | 
			
		||||
import com.recovery.common.base.config.redis.RedisCache;
 | 
			
		||||
import com.recovery.common.base.constant.Constants;
 | 
			
		||||
import com.recovery.common.base.result.ResultCode;
 | 
			
		||||
import com.recovery.common.base.util.RedisUtil;
 | 
			
		||||
| 
						 | 
				
			
			@ -27,10 +29,10 @@ import java.util.HashMap;
 | 
			
		|||
public class JwtInterceptor implements HandlerInterceptor {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    RedisUtil redisUtil;
 | 
			
		||||
    RedisCache redisCache;
 | 
			
		||||
 | 
			
		||||
    public JwtInterceptor(RedisUtil redisUtil) {
 | 
			
		||||
        this.redisUtil = redisUtil;
 | 
			
		||||
    public JwtInterceptor(RedisCache redisCache) {
 | 
			
		||||
        this.redisCache = redisCache;
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +47,10 @@ public class JwtInterceptor implements HandlerInterceptor {
 | 
			
		|||
        if (StringUtils.isEmpty(token)) {
 | 
			
		||||
            throw new BusinessException(ResultCode.LOGIN_ERROR);
 | 
			
		||||
        }
 | 
			
		||||
        boolean rest = redisUtil.hasKey("userToken:" +token);
 | 
			
		||||
        if (!StpUtil.isLogin()) {
 | 
			
		||||
            throw new BusinessException(ResultCode.IS_LOGIN_EXPIRE_ERROR);
 | 
			
		||||
        }
 | 
			
		||||
        boolean rest = redisCache.isExists(Constants.REDIS_USRE_TOKEN+token);
 | 
			
		||||
        if (!rest) {
 | 
			
		||||
            throw new BusinessException(ResultCode.LOGIN_EXPIRE_ERROR);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +58,8 @@ public class JwtInterceptor implements HandlerInterceptor {
 | 
			
		|||
        request.setAttribute(Constants.LOGIN_USRE_TOKEN,token);
 | 
			
		||||
        try {
 | 
			
		||||
            //如果验证成功放行请求
 | 
			
		||||
            DecodedJWT verify = JwtUtils.verifyToken(token);
 | 
			
		||||
//            DecodedJWT verify = JwtUtils.verifyToken(token);
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception exception)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ public class WebLogAspect {
 | 
			
		|||
        //切割获取访问目标模块
 | 
			
		||||
        String[] split = path.split("/");
 | 
			
		||||
        String module = split[0];
 | 
			
		||||
        System.out.println(RedisUtils.getDBInfoByHostAndModule(stringRedisTemplate,hospitalHost,"admin"));
 | 
			
		||||
        log.info(RedisUtils.getDBInfoByHostAndModule(stringRedisTemplate,hospitalHost,"admin")+"");
 | 
			
		||||
        //根据域名和请求的模块名查询目标数据库
 | 
			
		||||
        HttpSession session = request.getSession();
 | 
			
		||||
        /**
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +71,8 @@ public class WebLogAspect {
 | 
			
		|||
    //执行完切面后,将线程共享中的数据源名称清空
 | 
			
		||||
    @After("webLog()")
 | 
			
		||||
    public void after(JoinPoint joinPoint){
 | 
			
		||||
        //清除
 | 
			
		||||
        HspHostUtil.clear();
 | 
			
		||||
        DataSourceContextHolder.clearDBType();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,10 @@ package com.recovery.auth.config;
 | 
			
		|||
 | 
			
		||||
import cn.dev33.satoken.context.SaHolder;
 | 
			
		||||
import cn.dev33.satoken.filter.SaServletFilter;
 | 
			
		||||
import cn.dev33.satoken.jwt.StpLogicJwtForMixin;
 | 
			
		||||
import cn.dev33.satoken.jwt.StpLogicJwtForSimple;
 | 
			
		||||
import cn.dev33.satoken.same.SaSameUtil;
 | 
			
		||||
import cn.dev33.satoken.stp.StpLogic;
 | 
			
		||||
import cn.dev33.satoken.util.SaResult;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,4 +32,10 @@ public class SaTokenConfigure implements WebMvcConfigurer {
 | 
			
		|||
                })
 | 
			
		||||
                ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Sa-Token 整合 jwt (Simple 简单模式)
 | 
			
		||||
    @Bean
 | 
			
		||||
    public StpLogic getStpLogicJwt() {
 | 
			
		||||
        return new StpLogicJwtForSimple();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,10 +8,14 @@ import com.recovery.auth.exception.BusinessException;
 | 
			
		|||
import com.recovery.auth.feign.UserFeignClient;
 | 
			
		||||
import com.recovery.auth.security.details.user.JwtAuthenticationRequest;
 | 
			
		||||
import com.recovery.auth.service.AuthService;
 | 
			
		||||
import com.recovery.common.base.config.redis.RedisCache;
 | 
			
		||||
import com.recovery.common.base.constant.Constants;
 | 
			
		||||
import com.recovery.common.base.dto.UserAuthDTO;
 | 
			
		||||
import com.recovery.common.base.dto.UserAuthorityDto;
 | 
			
		||||
import com.recovery.common.base.result.ApiResult;
 | 
			
		||||
import com.recovery.common.base.result.ResultCode;
 | 
			
		||||
import com.recovery.common.base.util.EncryptUtil;
 | 
			
		||||
import com.recovery.common.base.util.RedisUtil;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.util.StringUtils;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +38,8 @@ public class AuthController {
 | 
			
		|||
    AuthService authService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    UserFeignClient userFeignClient;
 | 
			
		||||
    @Resource
 | 
			
		||||
    RedisCache redisCache;
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/token")
 | 
			
		||||
    public ApiResult postAccessToken(@RequestBody JwtAuthenticationRequest authenticationRequest, HttpServletRequest request){
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +54,8 @@ public class AuthController {
 | 
			
		|||
        return ApiResult.ok(map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/doLogin")
 | 
			
		||||
    public SaResult doLogin(@RequestBody JwtAuthenticationRequest authenticationRequest) {
 | 
			
		||||
    @PostMapping("/doLogin")
 | 
			
		||||
    public ApiResult doLogin(@RequestBody JwtAuthenticationRequest authenticationRequest) {
 | 
			
		||||
        if(StringUtils.isEmpty(authenticationRequest.getUsername())){
 | 
			
		||||
            throw new BusinessException("账户不能为空");
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -62,16 +68,25 @@ public class AuthController {
 | 
			
		|||
        if (ResultCode.SUCCESS.getCode().equals(result.getCode())) {
 | 
			
		||||
            userDetails = result.getData();
 | 
			
		||||
        }
 | 
			
		||||
        // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
 | 
			
		||||
        if (userDetails.getUserName().equals(authenticationRequest.getUsername()) && userDetails.getPassword().equals(authenticationRequest.getPassword())) {
 | 
			
		||||
        // 数据库中查询数据进行比对
 | 
			
		||||
        if (userDetails.getUserName().equals(authenticationRequest.getUsername()) && userDetails.getPassword().equals(EncryptUtil.encrypt(authenticationRequest.getPassword()))) {
 | 
			
		||||
            log.info("密码校验成功!");
 | 
			
		||||
            StpUtil.login(userDetails.getUserName());
 | 
			
		||||
            StpUtil.login(userDetails.getUserId(),"PC");
 | 
			
		||||
        }else {
 | 
			
		||||
            return SaResult.error("密码错误");
 | 
			
		||||
            return ApiResult.failed("密码错误");
 | 
			
		||||
        }
 | 
			
		||||
        //认证通过 使用userid 储存用户信息
 | 
			
		||||
        try {
 | 
			
		||||
            redisCache.put_obj(Constants.REDIS_USRE_INFO + userDetails.getUserId(),userDetails , Constants.REDIS_TOKEN_TIME);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error("redis储存token报错"+e.getMessage(),e);
 | 
			
		||||
        }
 | 
			
		||||
        // 第3步,返回给前端
 | 
			
		||||
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
 | 
			
		||||
        return SaResult.ok("登录成功").setData(tokenInfo);
 | 
			
		||||
        HashMap map= new HashMap();
 | 
			
		||||
        map.put("token",tokenInfo.getTokenValue());
 | 
			
		||||
        map.put("user",userDetails);
 | 
			
		||||
        return ApiResult.ok(map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    @GetMapping("/public-key")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,8 @@ spring:
 | 
			
		|||
  cloud:
 | 
			
		||||
    nacos:
 | 
			
		||||
      discovery:
 | 
			
		||||
        #        metadata:
 | 
			
		||||
        #          serviceGroup: ytChen
 | 
			
		||||
        metadata:
 | 
			
		||||
          serviceGroup: ytChen
 | 
			
		||||
        server-addr: localhost:8848
 | 
			
		||||
        namespace: 11bfd099-10d6-4f2c-b969-58b76e435cce
 | 
			
		||||
      config:
 | 
			
		||||
| 
						 | 
				
			
			@ -21,3 +21,15 @@ spring:
 | 
			
		|||
        namespace: 11bfd099-10d6-4f2c-b969-58b76e435cce
 | 
			
		||||
server:
 | 
			
		||||
  port: 9001
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
sa-token:
 | 
			
		||||
  # jwt秘钥
 | 
			
		||||
  jwt-secret-key: asdasdasifhueuiwyurfewbfjsdafjk123
 | 
			
		||||
  token-name: satoken
 | 
			
		||||
  timeout: -1
 | 
			
		||||
  active-timeout: -1
 | 
			
		||||
  is-concurrent: false
 | 
			
		||||
  is-share: false
 | 
			
		||||
  is-log: true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,17 @@ public class Constants {
 | 
			
		|||
    public final static String UPLOAD_SIZE_ERR_MSG = "上传大小错误";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static final String LOGIN_USRE_TOKEN = "x-userToken";
 | 
			
		||||
    public static final String LOGIN_USRE_TOKEN = "satoken";
 | 
			
		||||
 | 
			
		||||
    //token
 | 
			
		||||
    public static final String REDIS_USRE_TOKEN = "satoken:login:token:";
 | 
			
		||||
 | 
			
		||||
    //用户信息
 | 
			
		||||
    public static final String REDIS_USRE_INFO = "satoken:login:userInfo:";
 | 
			
		||||
 | 
			
		||||
    //token过期时间 七天
 | 
			
		||||
    public static final Integer REDIS_TOKEN_TIME = 7*24*60*60;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public final static String WHOLE_DOMAIN_REDIS_KEY = "HOE_WHOLE_DOMAIN_REDIS_KEY";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ public enum ResultCode implements IResultCode, Serializable {
 | 
			
		|||
    LOGIN_ERROR("1001", "未登录"),
 | 
			
		||||
 | 
			
		||||
    LOGIN_EXPIRE_ERROR("1002", "登录过期,请重新登录!"),
 | 
			
		||||
    IS_LOGIN_EXPIRE_ERROR("1003", "您已被踢下线,请重新登录!"),
 | 
			
		||||
    SYSTEM_EXECUTION_ERROR("999999", "系统执行出错"),
 | 
			
		||||
    USERNAME_OR_PASSWORD_ERROR("A00100", "用户名或密码错误"),
 | 
			
		||||
    USER_NOT_EXIST("A00101", "用户不存在"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,9 @@ public class HspHostUtil {
 | 
			
		|||
    public static void setHspHost(String hspHost) {
 | 
			
		||||
        HSP_HSOT.set(hspHost);
 | 
			
		||||
    }
 | 
			
		||||
    public static void clear() {
 | 
			
		||||
        HSP_HSOT.remove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,13 +54,11 @@
 | 
			
		|||
            <artifactId>httpclient</artifactId>
 | 
			
		||||
            <version>4.5.13</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        <!-- Sa-Token 权限认证(Reactor响应式集成),在线文档:https://sa-token.cc -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>cn.dev33</groupId>
 | 
			
		||||
            <artifactId>sa-token-reactor-spring-boot-starter</artifactId>
 | 
			
		||||
            <version>1.34.0</version>
 | 
			
		||||
            <version>1.37.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import cn.dev33.satoken.reactor.filter.SaReactorFilter;
 | 
			
		|||
import cn.dev33.satoken.router.SaRouter;
 | 
			
		||||
import cn.dev33.satoken.stp.StpUtil;
 | 
			
		||||
import cn.dev33.satoken.util.SaResult;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,31 +13,55 @@ import org.springframework.context.annotation.Configuration;
 | 
			
		|||
 * [Sa-Token 权限认证] 配置类
 | 
			
		||||
 */
 | 
			
		||||
@Configuration
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class SaTokenConfigure {
 | 
			
		||||
    // 注册 Sa-Token全局过滤器
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 注册 [Sa-Token全局过滤器]
 | 
			
		||||
     */
 | 
			
		||||
    @Bean
 | 
			
		||||
    public SaReactorFilter getSaReactorFilter() {
 | 
			
		||||
        return new SaReactorFilter()
 | 
			
		||||
                // 拦截地址
 | 
			
		||||
                .addInclude("/**")    /* 拦截全部path */
 | 
			
		||||
                // 开放地址
 | 
			
		||||
                // 指定 [拦截路由]
 | 
			
		||||
                .addInclude("/**")    /* 拦截所有path */
 | 
			
		||||
                // 指定 [放行路由]
 | 
			
		||||
                .addExclude("/favicon.ico")
 | 
			
		||||
                // 鉴权方法:每次访问进入
 | 
			
		||||
                // 指定[认证函数]: 每次请求执行
 | 
			
		||||
                .setAuth(obj -> {
 | 
			
		||||
                    // 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
 | 
			
		||||
                    SaRouter.match("/**", "/auth/oauth/doLogin", r -> StpUtil.checkLogin());
 | 
			
		||||
 | 
			
		||||
                    // 权限认证 -- 不同模块, 校验不同权限
 | 
			
		||||
                    SaRouter.match("/api/test1", r -> StpUtil.checkPermission("api.test1"));
 | 
			
		||||
                    SaRouter.match("/api/test2", r -> StpUtil.checkPermission("api.test2"));
 | 
			
		||||
                    SaRouter.match("/api/test3", r -> StpUtil.checkRoleOr("admin", "super"));
 | 
			
		||||
 | 
			
		||||
                    // 更多匹配 ...  */
 | 
			
		||||
                   log.info("---------- sa全局认证");
 | 
			
		||||
                    // SaRouter.match("/test/test", () -> StpUtil.checkLogin());
 | 
			
		||||
                })
 | 
			
		||||
                // 异常处理方法:每次setAuth函数出现异常时进入
 | 
			
		||||
                // 指定[异常处理函数]:每次[认证函数]发生异常时执行此函数
 | 
			
		||||
                .setError(e -> {
 | 
			
		||||
                    log.info("---------- sa全局异常 ");
 | 
			
		||||
                    return SaResult.error(e.getMessage());
 | 
			
		||||
                })
 | 
			
		||||
                ;
 | 
			
		||||
    }
 | 
			
		||||
    // 注册 Sa-Token全局过滤器
 | 
			
		||||
//    @Bean
 | 
			
		||||
//    public SaReactorFilter getSaReactorFilter() {
 | 
			
		||||
//        return new SaReactorFilter()
 | 
			
		||||
//                // 拦截地址
 | 
			
		||||
//                .addInclude("/**")    /* 拦截全部path */
 | 
			
		||||
//                // 开放地址
 | 
			
		||||
//                .addExclude("/favicon.ico")
 | 
			
		||||
//                // 鉴权方法:每次访问进入
 | 
			
		||||
//                .setAuth(obj -> {
 | 
			
		||||
//                    // 登录校验 -- 拦截所有路由,并排除/user/doLogin 用于开放登录
 | 
			
		||||
//                    SaRouter.match("/**", "/auth/oauth/doLogin", r -> StpUtil.checkLogin());
 | 
			
		||||
//
 | 
			
		||||
//                    // 权限认证 -- 不同模块, 校验不同权限
 | 
			
		||||
//                    SaRouter.match("/api/test1", r -> StpUtil.checkPermission("api.test1"));
 | 
			
		||||
//                    SaRouter.match("/api/test2", r -> StpUtil.checkPermission("api.test2"));
 | 
			
		||||
//                    SaRouter.match("/api/test3", r -> StpUtil.checkRoleOr("admin", "super"));
 | 
			
		||||
//
 | 
			
		||||
//                    // 更多匹配 ...  */
 | 
			
		||||
//                })
 | 
			
		||||
//                // 异常处理方法:每次setAuth函数出现异常时进入
 | 
			
		||||
//                .setError(e -> {
 | 
			
		||||
//                    return SaResult.error(e.getMessage());
 | 
			
		||||
//                })
 | 
			
		||||
//                ;
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,80 +1,80 @@
 | 
			
		|||
//package com.recovery.gateway.security;
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
//import com.recovery.common.base.result.ResultCode;
 | 
			
		||||
//import com.recovery.gateway.util.ResponseUtils;
 | 
			
		||||
//import lombok.AllArgsConstructor;
 | 
			
		||||
//import org.springframework.context.annotation.Bean;
 | 
			
		||||
//import org.springframework.context.annotation.Configuration;
 | 
			
		||||
//import org.springframework.core.convert.converter.Converter;
 | 
			
		||||
//import org.springframework.security.authentication.AbstractAuthenticationToken;
 | 
			
		||||
//import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 | 
			
		||||
//import org.springframework.security.config.web.server.ServerHttpSecurity;
 | 
			
		||||
//import org.springframework.security.oauth2.jwt.Jwt;
 | 
			
		||||
//import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
 | 
			
		||||
//import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
 | 
			
		||||
//import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
 | 
			
		||||
//import org.springframework.security.web.server.SecurityWebFilterChain;
 | 
			
		||||
//import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
 | 
			
		||||
//import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
 | 
			
		||||
//import reactor.core.publisher.Mono;
 | 
			
		||||
///**
 | 
			
		||||
// * @author:
 | 
			
		||||
// */
 | 
			
		||||
//@AllArgsConstructor
 | 
			
		||||
//@Configuration
 | 
			
		||||
//@EnableWebFluxSecurity
 | 
			
		||||
//public class ResourceServerConfig {
 | 
			
		||||
//
 | 
			
		||||
//    private final ResourceServerManager resourceServerManager;
 | 
			
		||||
//
 | 
			
		||||
//    @Bean
 | 
			
		||||
//    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
 | 
			
		||||
//        http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
 | 
			
		||||
//        http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
 | 
			
		||||
//        http.authorizeExchange()
 | 
			
		||||
//                .anyExchange().access(resourceServerManager)
 | 
			
		||||
//                .and()
 | 
			
		||||
//                .exceptionHandling()
 | 
			
		||||
//                .accessDeniedHandler(accessDeniedHandler()) // 处理未授权
 | 
			
		||||
//                .authenticationEntryPoint(authenticationEntryPoint()) //处理未认证
 | 
			
		||||
//                .and().csrf().disable();
 | 
			
		||||
//        return http.build();
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * 自定义未授权响应
 | 
			
		||||
//     */
 | 
			
		||||
//    @Bean
 | 
			
		||||
//    ServerAccessDeniedHandler accessDeniedHandler() {
 | 
			
		||||
//        return (exchange, denied) -> {
 | 
			
		||||
//            Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
 | 
			
		||||
//                    .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.ACCESS_UNAUTHORIZED));
 | 
			
		||||
//            return mono;
 | 
			
		||||
//        };
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * token无效或者已过期自定义响应
 | 
			
		||||
//     */
 | 
			
		||||
//    @Bean
 | 
			
		||||
//    ServerAuthenticationEntryPoint authenticationEntryPoint() {
 | 
			
		||||
//        return (exchange, e) -> {
 | 
			
		||||
//            Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
 | 
			
		||||
//                    .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.TOKEN_INVALID_OR_EXPIRED));
 | 
			
		||||
//            return mono;
 | 
			
		||||
//        };
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Bean
 | 
			
		||||
//    public Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter() {
 | 
			
		||||
//        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 | 
			
		||||
//        jwtGrantedAuthoritiesConverter.setAuthorityPrefix(SecurityConstants.AUTHORITY_PREFIX);
 | 
			
		||||
//        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityConstants.JWT_AUTHORITIES_KEY);
 | 
			
		||||
//
 | 
			
		||||
//        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
 | 
			
		||||
//        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
 | 
			
		||||
//        return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
package com.recovery.gateway.security;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
import com.recovery.common.base.result.ResultCode;
 | 
			
		||||
import com.recovery.gateway.util.ResponseUtils;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.core.convert.converter.Converter;
 | 
			
		||||
import org.springframework.security.authentication.AbstractAuthenticationToken;
 | 
			
		||||
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
 | 
			
		||||
import org.springframework.security.config.web.server.ServerHttpSecurity;
 | 
			
		||||
import org.springframework.security.oauth2.jwt.Jwt;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
 | 
			
		||||
import org.springframework.security.oauth2.server.resource.authentication.ReactiveJwtAuthenticationConverterAdapter;
 | 
			
		||||
import org.springframework.security.web.server.SecurityWebFilterChain;
 | 
			
		||||
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
 | 
			
		||||
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
 | 
			
		||||
import reactor.core.publisher.Mono;
 | 
			
		||||
/**
 | 
			
		||||
 * @author:
 | 
			
		||||
 */
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
@Configuration
 | 
			
		||||
@EnableWebFluxSecurity
 | 
			
		||||
public class ResourceServerConfig {
 | 
			
		||||
 | 
			
		||||
    private final ResourceServerManager resourceServerManager;
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
 | 
			
		||||
        http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());
 | 
			
		||||
        http.oauth2ResourceServer().authenticationEntryPoint(authenticationEntryPoint());
 | 
			
		||||
        http.authorizeExchange()
 | 
			
		||||
                .anyExchange().access(resourceServerManager)
 | 
			
		||||
                .and()
 | 
			
		||||
                .exceptionHandling()
 | 
			
		||||
                .accessDeniedHandler(accessDeniedHandler()) // 处理未授权
 | 
			
		||||
                .authenticationEntryPoint(authenticationEntryPoint()) //处理未认证
 | 
			
		||||
                .and().csrf().disable();
 | 
			
		||||
        return http.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 自定义未授权响应
 | 
			
		||||
     */
 | 
			
		||||
    @Bean
 | 
			
		||||
    ServerAccessDeniedHandler accessDeniedHandler() {
 | 
			
		||||
        return (exchange, denied) -> {
 | 
			
		||||
            Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
 | 
			
		||||
                    .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.ACCESS_UNAUTHORIZED));
 | 
			
		||||
            return mono;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * token无效或者已过期自定义响应
 | 
			
		||||
     */
 | 
			
		||||
    @Bean
 | 
			
		||||
    ServerAuthenticationEntryPoint authenticationEntryPoint() {
 | 
			
		||||
        return (exchange, e) -> {
 | 
			
		||||
            Mono<Void> mono = Mono.defer(() -> Mono.just(exchange.getResponse()))
 | 
			
		||||
                    .flatMap(response -> ResponseUtils.writeErrorInfo(response, ResultCode.TOKEN_INVALID_OR_EXPIRED));
 | 
			
		||||
            return mono;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Bean
 | 
			
		||||
    public Converter<Jwt, ? extends Mono<? extends AbstractAuthenticationToken>> jwtAuthenticationConverter() {
 | 
			
		||||
        JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
 | 
			
		||||
        jwtGrantedAuthoritiesConverter.setAuthorityPrefix(SecurityConstants.AUTHORITY_PREFIX);
 | 
			
		||||
        jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName(SecurityConstants.JWT_AUTHORITIES_KEY);
 | 
			
		||||
 | 
			
		||||
        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
 | 
			
		||||
        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);
 | 
			
		||||
        return new ReactiveJwtAuthenticationConverterAdapter(jwtAuthenticationConverter);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,79 +1,79 @@
 | 
			
		|||
//package com.recovery.gateway.security;
 | 
			
		||||
//
 | 
			
		||||
//import cn.hutool.core.collection.CollectionUtil;
 | 
			
		||||
//import cn.hutool.core.convert.Convert;
 | 
			
		||||
//import cn.hutool.core.util.StrUtil;
 | 
			
		||||
//
 | 
			
		||||
//import com.recovery.common.base.constant.GlobalConstants;
 | 
			
		||||
//import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
//import com.recovery.gateway.util.UrlPatternUtils;
 | 
			
		||||
//import lombok.RequiredArgsConstructor;
 | 
			
		||||
//import lombok.Setter;
 | 
			
		||||
//import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
//import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
//import org.springframework.data.redis.core.RedisTemplate;
 | 
			
		||||
//import org.springframework.http.HttpMethod;
 | 
			
		||||
//import org.springframework.http.server.reactive.ServerHttpRequest;
 | 
			
		||||
//import org.springframework.security.authorization.AuthorizationDecision;
 | 
			
		||||
//import org.springframework.security.authorization.ReactiveAuthorizationManager;
 | 
			
		||||
//import org.springframework.security.core.Authentication;
 | 
			
		||||
//import org.springframework.security.core.GrantedAuthority;
 | 
			
		||||
//import org.springframework.security.web.server.authorization.AuthorizationContext;
 | 
			
		||||
//import org.springframework.stereotype.Component;
 | 
			
		||||
//import org.springframework.util.AntPathMatcher;
 | 
			
		||||
//import org.springframework.util.PathMatcher;
 | 
			
		||||
//import reactor.core.publisher.Mono;
 | 
			
		||||
//
 | 
			
		||||
//import java.util.ArrayList;
 | 
			
		||||
//import java.util.List;
 | 
			
		||||
//import java.util.Map;
 | 
			
		||||
///**
 | 
			
		||||
// * Created with IntelliJ IDEA.
 | 
			
		||||
// *
 | 
			
		||||
// * @author:
 | 
			
		||||
// * @date: 2021/11/24
 | 
			
		||||
// * @description:
 | 
			
		||||
// * @modifiedBy:
 | 
			
		||||
// * @version: 1.0
 | 
			
		||||
// */
 | 
			
		||||
//@Component
 | 
			
		||||
//@RequiredArgsConstructor
 | 
			
		||||
//@Slf4j
 | 
			
		||||
//@ConfigurationProperties(prefix = "security")
 | 
			
		||||
//public class ResourceServerManager implements ReactiveAuthorizationManager<AuthorizationContext> {
 | 
			
		||||
//    private final RedisTemplate redisTemplate;
 | 
			
		||||
//
 | 
			
		||||
//    @Setter
 | 
			
		||||
//    private List<String> ignoreUrls;
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
 | 
			
		||||
//        ServerHttpRequest request = authorizationContext.getExchange().getRequest();
 | 
			
		||||
//        if (request.getMethod() == HttpMethod.OPTIONS) { // 预检请求放行
 | 
			
		||||
//            return Mono.just(new AuthorizationDecision(true));
 | 
			
		||||
//        }
 | 
			
		||||
//        PathMatcher pathMatcher = new AntPathMatcher();
 | 
			
		||||
//        String method = request.getMethodValue();
 | 
			
		||||
//        String path = request.getURI().getPath();
 | 
			
		||||
//
 | 
			
		||||
//        // 跳过token校验,放在这里去做是为了能够动态刷新
 | 
			
		||||
////        if (skipValid(path)) {
 | 
			
		||||
//            return Mono.just(new AuthorizationDecision(true));
 | 
			
		||||
////        }
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    /**
 | 
			
		||||
//     * 跳过校验
 | 
			
		||||
//     *
 | 
			
		||||
//     * @param path
 | 
			
		||||
//     * @return
 | 
			
		||||
//     */
 | 
			
		||||
//    private boolean skipValid(String path) {
 | 
			
		||||
//        for (String skipPath : ignoreUrls) {
 | 
			
		||||
//            if (UrlPatternUtils.match(skipPath, path)) {
 | 
			
		||||
//                return true;
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//        return false;
 | 
			
		||||
//    }
 | 
			
		||||
package com.recovery.gateway.security;
 | 
			
		||||
 | 
			
		||||
import cn.hutool.core.collection.CollectionUtil;
 | 
			
		||||
import cn.hutool.core.convert.Convert;
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
 | 
			
		||||
import com.recovery.common.base.constant.GlobalConstants;
 | 
			
		||||
import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
import com.recovery.gateway.util.UrlPatternUtils;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.Setter;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.boot.context.properties.ConfigurationProperties;
 | 
			
		||||
import org.springframework.data.redis.core.RedisTemplate;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
import org.springframework.http.server.reactive.ServerHttpRequest;
 | 
			
		||||
import org.springframework.security.authorization.AuthorizationDecision;
 | 
			
		||||
import org.springframework.security.authorization.ReactiveAuthorizationManager;
 | 
			
		||||
import org.springframework.security.core.Authentication;
 | 
			
		||||
import org.springframework.security.core.GrantedAuthority;
 | 
			
		||||
import org.springframework.security.web.server.authorization.AuthorizationContext;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.util.AntPathMatcher;
 | 
			
		||||
import org.springframework.util.PathMatcher;
 | 
			
		||||
import reactor.core.publisher.Mono;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
/**
 | 
			
		||||
 * Created with IntelliJ IDEA.
 | 
			
		||||
 *
 | 
			
		||||
 * @author:
 | 
			
		||||
 * @date: 2021/11/24
 | 
			
		||||
 * @description:
 | 
			
		||||
 * @modifiedBy:
 | 
			
		||||
 * @version: 1.0
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
@Slf4j
 | 
			
		||||
@ConfigurationProperties(prefix = "security")
 | 
			
		||||
public class ResourceServerManager implements ReactiveAuthorizationManager<AuthorizationContext> {
 | 
			
		||||
    private final RedisTemplate redisTemplate;
 | 
			
		||||
 | 
			
		||||
    @Setter
 | 
			
		||||
    private List<String> ignoreUrls;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {
 | 
			
		||||
        ServerHttpRequest request = authorizationContext.getExchange().getRequest();
 | 
			
		||||
        if (request.getMethod() == HttpMethod.OPTIONS) { // 预检请求放行
 | 
			
		||||
            return Mono.just(new AuthorizationDecision(true));
 | 
			
		||||
        }
 | 
			
		||||
        PathMatcher pathMatcher = new AntPathMatcher();
 | 
			
		||||
        String method = request.getMethodValue();
 | 
			
		||||
        String path = request.getURI().getPath();
 | 
			
		||||
 | 
			
		||||
        // 跳过token校验,放在这里去做是为了能够动态刷新
 | 
			
		||||
//        if (skipValid(path)) {
 | 
			
		||||
            return Mono.just(new AuthorizationDecision(true));
 | 
			
		||||
//        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 跳过校验
 | 
			
		||||
     *
 | 
			
		||||
     * @param path
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private boolean skipValid(String path) {
 | 
			
		||||
        for (String skipPath : ignoreUrls) {
 | 
			
		||||
            if (UrlPatternUtils.match(skipPath, path)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +1,57 @@
 | 
			
		|||
//package com.recovery.gateway.security;
 | 
			
		||||
//
 | 
			
		||||
//import cn.dev33.satoken.same.SaSameUtil;
 | 
			
		||||
//import cn.hutool.core.util.StrUtil;
 | 
			
		||||
//
 | 
			
		||||
//import com.nimbusds.jose.JWSObject;
 | 
			
		||||
//import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
//import lombok.RequiredArgsConstructor;
 | 
			
		||||
//import lombok.SneakyThrows;
 | 
			
		||||
//import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
//import org.apache.logging.log4j.util.Strings;
 | 
			
		||||
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
 | 
			
		||||
//import org.springframework.cloud.gateway.filter.GlobalFilter;
 | 
			
		||||
//import org.springframework.core.Ordered;
 | 
			
		||||
//import org.springframework.data.redis.core.RedisTemplate;
 | 
			
		||||
//import org.springframework.http.server.reactive.ServerHttpRequest;
 | 
			
		||||
//import org.springframework.http.server.reactive.ServerHttpResponse;
 | 
			
		||||
//import org.springframework.stereotype.Component;
 | 
			
		||||
//import org.springframework.web.server.ServerWebExchange;
 | 
			
		||||
//import reactor.core.publisher.Mono;
 | 
			
		||||
//
 | 
			
		||||
//import java.net.URLEncoder;
 | 
			
		||||
///**
 | 
			
		||||
// * Created with IntelliJ IDEA.
 | 
			
		||||
// *
 | 
			
		||||
// * @author: AI码师 关注公众号"AI码师"获取完整源码
 | 
			
		||||
// * @date: 2021/11/24
 | 
			
		||||
// * @description:
 | 
			
		||||
// * @modifiedBy:
 | 
			
		||||
// * @version: 1.0
 | 
			
		||||
// */
 | 
			
		||||
//@Component
 | 
			
		||||
//@Slf4j
 | 
			
		||||
//@RequiredArgsConstructor
 | 
			
		||||
//public class SecurityGlobalFilter implements GlobalFilter, Ordered {
 | 
			
		||||
//
 | 
			
		||||
//    @SneakyThrows
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 | 
			
		||||
//
 | 
			
		||||
//        ServerHttpRequest request = exchange.getRequest();
 | 
			
		||||
//        log.info("接受到请求地址:"+request.getURI());
 | 
			
		||||
//        ServerHttpResponse response = exchange.getResponse();
 | 
			
		||||
//        // 不是正确的的JWT不做解析处理
 | 
			
		||||
//        String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_KEY);
 | 
			
		||||
//        if (StrUtil.isBlank(token) || !StrUtil.startWithIgnoreCase(token, SecurityConstants.JWT_PREFIX)) {
 | 
			
		||||
//            return chain.filter(exchange);
 | 
			
		||||
//        }
 | 
			
		||||
//        // 为请求追加 Same-Token 参数
 | 
			
		||||
//        request.mutate()
 | 
			
		||||
//                // 为请求追加 Same-Token 参数
 | 
			
		||||
//                .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken())
 | 
			
		||||
//                .build();
 | 
			
		||||
//        //结束
 | 
			
		||||
//        // 解析JWT获取jti,以jti为key判断redis的黑名单列表是否存在,存在则拦截访问
 | 
			
		||||
//        token = StrUtil.replaceIgnoreCase(token, SecurityConstants.JWT_PREFIX, Strings.EMPTY);
 | 
			
		||||
//        String payload = StrUtil.toString(JWSObject.parse(token).getPayload());
 | 
			
		||||
//        request = exchange.getRequest().mutate()
 | 
			
		||||
//                .header(SecurityConstants.JWT_PAYLOAD_KEY, URLEncoder.encode(payload, "UTF-8"))
 | 
			
		||||
//                .build();
 | 
			
		||||
//        exchange = exchange.mutate().request(request).build();
 | 
			
		||||
//        return chain.filter(exchange);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    @Override
 | 
			
		||||
//    public int getOrder() {
 | 
			
		||||
//        return 0;
 | 
			
		||||
//    }
 | 
			
		||||
//}
 | 
			
		||||
package com.recovery.gateway.security;
 | 
			
		||||
 | 
			
		||||
import cn.dev33.satoken.same.SaSameUtil;
 | 
			
		||||
import cn.hutool.core.util.StrUtil;
 | 
			
		||||
 | 
			
		||||
import com.nimbusds.jose.JWSObject;
 | 
			
		||||
import com.recovery.common.base.constant.SecurityConstants;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.SneakyThrows;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.apache.logging.log4j.util.Strings;
 | 
			
		||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
 | 
			
		||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
 | 
			
		||||
import org.springframework.core.Ordered;
 | 
			
		||||
import org.springframework.data.redis.core.RedisTemplate;
 | 
			
		||||
import org.springframework.http.server.reactive.ServerHttpRequest;
 | 
			
		||||
import org.springframework.http.server.reactive.ServerHttpResponse;
 | 
			
		||||
import org.springframework.stereotype.Component;
 | 
			
		||||
import org.springframework.web.server.ServerWebExchange;
 | 
			
		||||
import reactor.core.publisher.Mono;
 | 
			
		||||
 | 
			
		||||
import java.net.URLEncoder;
 | 
			
		||||
/**
 | 
			
		||||
 * Created with IntelliJ IDEA.
 | 
			
		||||
 *
 | 
			
		||||
 * @author:
 | 
			
		||||
 * @date: 2021/11/24
 | 
			
		||||
 * @description:
 | 
			
		||||
 * @modifiedBy:
 | 
			
		||||
 * @version: 1.0
 | 
			
		||||
 */
 | 
			
		||||
@Component
 | 
			
		||||
@Slf4j
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class SecurityGlobalFilter implements GlobalFilter, Ordered {
 | 
			
		||||
 | 
			
		||||
    @SneakyThrows
 | 
			
		||||
    @Override
 | 
			
		||||
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 | 
			
		||||
 | 
			
		||||
        ServerHttpRequest request = exchange.getRequest();
 | 
			
		||||
        log.info("接受到请求地址:"+request.getURI());
 | 
			
		||||
        ServerHttpResponse response = exchange.getResponse();
 | 
			
		||||
        // 为请求追加 Same-Token 参数
 | 
			
		||||
        request.mutate()
 | 
			
		||||
                // 为请求追加 Same-Token 参数
 | 
			
		||||
                .header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken())
 | 
			
		||||
                .build();
 | 
			
		||||
        exchange = exchange.mutate().request(request).build();
 | 
			
		||||
        return chain.filter(exchange);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getOrder() {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								pom.xml
								
								
								
								
							
							
						
						
									
										8
									
								
								pom.xml
								
								
								
								
							| 
						 | 
				
			
			@ -24,7 +24,7 @@
 | 
			
		|||
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
 | 
			
		||||
        <spring-boot.version>2.5.4</spring-boot.version>
 | 
			
		||||
        <hoe-version>1.0.0</hoe-version>
 | 
			
		||||
        <hutool-version>5.5.8</hutool-version>
 | 
			
		||||
        <hutool-version>5.7.14</hutool-version>
 | 
			
		||||
        <mysql.version>8.0.22</mysql.version>
 | 
			
		||||
        <druid.version>1.2.4</druid.version>
 | 
			
		||||
        <mybatis-plus.version>3.4.3</mybatis-plus.version>
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +52,12 @@
 | 
			
		|||
            <artifactId>sa-token-redis-jackson</artifactId>
 | 
			
		||||
            <version>1.37.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- Sa-Token 整合 jwt -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>cn.dev33</groupId>
 | 
			
		||||
            <artifactId>sa-token-jwt</artifactId>
 | 
			
		||||
            <version>1.37.0</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.commons</groupId>
 | 
			
		||||
            <artifactId>commons-pool2</artifactId>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue