自定义拦截器

 

@Component
public class UserTokenInterceptor implements HandlerInterceptor {

    @Autowired
    JwtTokenManagerProperties jwtTokenManagerProperties;

    @Autowired
    RedisTemplate<String, String> redisTemplate;  //用户获取redis数据

    //Spring路径匹配器AntPathMatcher
    private AntPathMatcher antPathMatcher = new AntPathMatcher();


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1. 判断是否请求 controller中的方法  ,如果不是 直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        //2. 从请求头中获取令牌 , Authorization
        String token = request.getHeader("Authorization");
        //3. 校验令牌是否为空 , 为空返回401
        if (StrUtil.isEmpty(token)) {
            //权限不足
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);
        }
        //4. 解析令牌,  并校验
        Claims claims = JwtUtil.parseJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(), token);
        //如果claims为空 , 则抛异常
        if (claims == null) {
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);
        }

        //5. 获取用户数据 UserVo  返回object类型
        String jsonStr = String.valueOf(claims.get("currentUser"));
        //5.1 转为 UserVo
        UserVo userVo = JSONUtil.toBean(jsonStr, UserVo.class);

        //6. 取用户id 然后从redis中获取 该用户所能访问的 , 所有资源列表(包含按钮资源列表 和白名单列表)
        Long userVoId = userVo.getId();
        String urlStr = redisTemplate.opsForValue().get(CacheConstant.PUBLIC_ACCESS_URLS + userVo.getId());
        //6.1 转为集合
        List<String> urls = JSONUtil.toList(urlStr, String.class);

        //7. 校验当前要访问的 资源 是否在用户所能访问的所有资源列表中
        //7.1 获取当前要访问的资源路径  方法加路径
        String target = request.getMethod() + request.getRequestURI();
        //7.2 遍历集合和 当前要访问的资源路径 做比较
        for (String url : urls) {
            if (antPathMatcher.match(url, target)) {
                //9. 如果在 将用户信息存入threadLocal 并放行
                UserThreadLocal.setSubject(jsonStr);
                return true;
            }
        }
        //8. 如果不在 , 则说明没有权限访问该资源 返回403
        throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_ERROR);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //清除threadLocal中的数据 防止内存泄漏
        UserThreadLocal.removeSubject();
    }
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值