SpringSecurity+JWT 登录授权过滤器

Posted 光脚造轮子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringSecurity+JWT 登录授权过滤器相关的知识,希望对你有一定的参考价值。

每次请求都会”携带“ token( token 在 request 的 header 里面)

拦截验证过程:

  request -> header -> token -> username -> userDetails(getAuthentication()) -> authentication

  SecurityContextHolder.getContext().setAuthentication(authentication)  //建立安全上下文

代码

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Value("${jwt.tokenHeader}")
    private String tokenHeader;
    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException,IOException {
        //request 中获取去 header
        String authHeader = request.getHeader(this.tokenHeader);
        //对header做判断
        if (authHeader != null && authHeader.startsWith(this.tokenHeader)) {
            //取出header
            //此处注意token之前有一个7字符长度的“Bearer “,
            String authToken = authHeader.substring(this.tokenHeader.length());// The part after "Bearer "
            //token中获取username
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            LOGGER.info("checking username:{}", username);
            //判断username
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                //拿到userDetails
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                //验证token
                if (jwtTokenUtil.validateToken(authToken,userDetails)) {
                    //完整填充的 authentication(其中包含了权限集 getAuthorities())
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    LOGGER.info("authenticated user:{}", username);
                    //建立安全上下文
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);
    }
}

UserDetails

public interface UserDetails extends Serializable {
    //用户的权限集,
    Collection<? extends GrantedAuthority> getAuthorities();
    //用户的加密后的密码, 不加密会使用`{noop}`前缀
    String getPassword();
    //应用内唯一的用户名
    String getUsername();
    //账户是否过期
    boolean isAccountNonExpired();
    //账户是否锁定
    boolean isAccountNonLocked();
    //凭证是否过期
    boolean isCredentialsNonExpired();
    //用户是否可用
    boolean isEnabled();
}

 

以上是关于SpringSecurity+JWT 登录授权过滤器的主要内容,如果未能解决你的问题,请参考以下文章

第十一篇SpringSecurity基于JWT实现Token的处理

Spring Security----JWT详解

微服务之间的通讯安全-JWT优化之日志错误处理限流及JWT改造后执行流程梳理

spring boot整合jwt 实现前后端分离登录认证及授权

手把手教你如何使用Spring Security(中):接口认证

SpringSecurity整合JWT-详细版