Bootstrap

JWT过滤器

package com.example.springsecurity3.hndler;

import com.example.springsecurity3.service.impl.SecurityService;
import com.example.springsecurity3.utils.JWTUtils;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * security整合jwt用的过滤器
 * 1:判断除登录请求外,是否携带jwt,如果没有携带,放行不处理(过滤连上的其他过滤器会处理)
 * 2:判断携带的jwt是否合法(),不合法,放行不处理
 * 3:拿redis的jwt和携带的jwt做对比
 *      一:redis的jwt已过期,放掉不处理
 *      二:把双方的jwt的值进行对比
 */
@Component
public class JWTFilter extends OncePerRequestFilter {
    @Autowired(required = false)
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private SecurityService securityService;
    //帮我们处理异常
    @SneakyThrows
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        //在请求头拿到jwt
        String jwt = request.getHeader("jwt");
        if (jwt==null){
            //放给security其他处理器处理此方法,该方法不做处理
            filterChain.doFilter(request,response);
            return;
        }
        //如果jwt不合法,则放行,给其他过滤器处理
        if (!JWTUtils.getDecrypt(jwt)){
            filterChain.doFilter(request,response);
            return;
        }
        //获取jwt的用户信息(通过jwt工具类的获取载荷方法拿去)
        Map account = JWTUtils.getAccount(jwt);
        //获取username
        String username = (String) account.get("username");
        //拿到redis的jwt
        String redisJwt = redisTemplate.opsForValue().get("jwt:" + username);
       //如果redis中的jwt过期怎不处理放行
        if (redisJwt==null){
            filterChain.doFilter(request,response);
            return;
        }
        //判断jwt是否和redis中的jwt相等
        if (!jwt.equals(redisJwt)){
            filterChain.doFilter(request,response);
            return;
        }
        //给redis的jwt续期
        redisTemplate.opsForValue().set("jwt:"+username,
                jwt,15, TimeUnit.MINUTES);

        //生成()凭证(通过SecurityService类中的loadUserByUsername方法获取用户名,密码,和权限)或者重新在usersDao中心方法从数据库中获取
        UserDetails userDetails = securityService.loadUserByUsername(username);
        //
        UsernamePasswordAuthenticationToken upa=new UsernamePasswordAuthenticationToken(
                //通过SecurityService类中的方法获取(用户名,密码,权限)
                userDetails.getUsername(),userDetails.getPassword(),userDetails.getAuthorities());
        //往security容器中注入凭证(用户名,密码,权限)
        SecurityContextHolder.getContext().setAuthentication(upa);
        //本方法功能执行完毕,交给下一个过滤器
        filterChain.doFilter(request,response);
    }
}

;