为什么刷新访问令牌会遭到未授权?

时间:2019-11-10 12:57:46

标签: java spring-boot jwt

随着访问令牌过期,客户端将使用/ refresh终结点发送GET请求,但以401-unauthorized结尾。

我已经在webConfig中配置了此请求。因此,它不需要授权。我已经在/ refresh请求的标头中传递了访问令牌。

注意:如果我未在/ refresh请求的标头中传递令牌,则效果很好。

JwtAuthenticationController.java:

@RestController
public class JwtAuthenticationController {

    @RequestMapping(value = "/refresh", method = RequestMethod.GET)
    public ResponseEntity<?> refreshAuthenticationToken(HttpServletRequest request) {

        final String token = request.getHeader("Authorization");

        final String username = jwtUtils.getUsernameFromToken(token);
        final UserDetails user =  userDetailsService.loadUserByUsername(username);

        if ((user.getUsername()).equals(username) && jwtUtils.isTokenExpired(token)) {
            final String refreshedToken = jwtUtils.refreshToken(token);
            return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken));
        } 
        else {
            return ResponseEntity.badRequest().body(null);
        }
    }
}

WebSecurityConfig.java

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf().disable()             
                .exceptionHandling()
               .antMatchers("/register","/refresh")
               .permitAll()                   
               .anyRequest().authenticated();                     

        httpSecurity.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
        httpSecurity.headers().cacheControl().disable();
    }
}

JwtAuthenticationFilter.java

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException {
        String authToken = request.getHeader(AUTHORIZATION_HEADER);

        if (authToken != null && authToken.startsWith(BEARER_PREFIX)) {
            try {
                authToken = authToken.substring(BEARER_PREFIX_LENGTH);
                username = jwtUtils.getUsernameFromToken(authToken);
            }catch (IllegalArgumentException e) {
                System.out.println("Unable to get JWT Token");
            } catch (ExpiredJwtException e) {
                System.out.println("JWT Token has expired");
            }
        }
        else {
        logger.warn("JWT Token does not begin with Bearer String");
   }
}

JwtUtils.java

private Claims getClaimsFromToken(String token) {
     return Jwts.parser()
                .setSigningKey(secret)
                .requireIssuer(issuer)
                .parseClaimsJws(token)
                .getBody();
}

error log

我不知道为什么会这样?使用客户端发送的刷新令牌来获取新访问令牌的解决方案是什么?

1 个答案:

答案 0 :(得分:0)

  

如果我未在/ refresh请求的标头中传递令牌,则效果很好。

这可能是因为JwtAuthenticationFilter。我认为您也应该从支票中排除/refresh,所以:

   if (!request.getRequestURI().contains("/refresh") {
    if (authToken != null && authToken.startsWith(BEARER_PREFIX)) {
    //same logic
    }
   }