SpringSecurity+Jwt遇到的bug


最近在使用springsecurity整合Jwt的时候,遇到了一Bug,卡住了很久,记录一下。

编写Jwt工具类JwtUtil,编写Jwt认证的核心过滤器JwtAuthenticationFilter(继承OncePerRequestFilter),重写过滤器方法doFilterInternal,本来的逻辑应该是从request中获取请求头,查看请求头中是否有token,有token并且token未失效,就让用户登录,并且new一个UsernamePasswordAuthenticationToken类,并设置到security的全局SecurityContextHolder中。最后放行,但是由于把放行的步骤写到if语句里面了,导致访问8080端口什么也获取不到。

下面是错误代码:

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String authHeader=request.getHeader(tokenHeader);
        //存在token
        if (null!=authHeader&&authHeader.startsWith(tokenHead))
        {
            String authToken=authHeader.substring(tokenHead.length());
            String username = jwtTokenUtil.getUsernameFromToken(authToken);
            //token存在但是未登录
            if (null!=username&&null==SecurityContextHolder.getContext().getAuthentication())
            {
                //登录
                User user = userService.findUserByUsername(username);
                //判断token是否有效
                if (jwtTokenUtil.validateToken(authToken,user))
                {
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=
                            new UsernamePasswordAuthenticationToken(user,null, null);
                    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
        	chain.doFilter(request,response);
        }
    }

chain.doFilter(request,response);方法放到里面去了肯定就是不会放行的,所有访问页面自然啥都不会有,既不报错,也不被springsecurity拦截。

正确代码:

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String authHeader=request.getHeader(tokenHeader);
        //存在token
        if (null!=authHeader&&authHeader.startsWith(tokenHead))
        {
            String authToken=authHeader.substring(tokenHead.length());
            String username = jwtTokenUtil.getUsernameFromToken(authToken);
            //token存在但是未登录
            if (null!=username&&null==SecurityContextHolder.getContext().getAuthentication())
            {
                //登录
                User user = userService.findUserByUsername(username);
                //判断token是否有效
                if (jwtTokenUtil.validateToken(authToken,user))
                {
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=
                            new UsernamePasswordAuthenticationToken(user,null, null);
                    usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
        }
        chain.doFilter(request,response);
    }

在经历过一次bug过后似乎就会理解得更深,尽管它很费时间,或许也是一种帮助吧。