Spring Boot + Security + JWT 无法生成令牌

Posted

技术标签:

【中文标题】Spring Boot + Security + JWT 无法生成令牌【英文标题】:Spring Boot + Security + JWT can't generate token 【发布时间】:2017-10-03 09:48:40 【问题描述】:

我用 JWT 配置了 Spring Boot 和安全性,有一段时间一切都很顺利。

这是我的 webSecurityConfig

httpSecurity
            .csrf().disable()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
            .authorizeRequests()
            .antMatchers(HttpMethod.POST, "/user/cadastrar/**").permitAll()
            .antMatchers(HttpMethod.POST, "/auth/**").permitAll()
            .anyRequest().authenticated();
    httpSecurity
            .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
    httpSecurity.headers().cacheControl();

第一条路线“/users/cadastrar”工作正常。

问题是我的第二条路线“/auth” 在主体上使用用户名和密码调用 /auth 它将登陆我的 JwtAuthenticationTokenFilter 类中的此函数

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException 
    String authToken = request.getHeader(this.tokenHeader);
    String username = jwtTokenUtil.getUsernameFromToken(authToken);
    logger.info("checking authentication for user " + username);
    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) 
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
        if (jwtTokenUtil.validateToken(authToken, userDetails)) 
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
            logger.info("authenticated user " + username + ", setting security context");
            SecurityContextHolder.getContext().setAuthentication(authentication);
        
    
    chain.doFilter(request, response);

然后它会去我的AuthenticationController类运行这个函数

@RequestMapping(value = "$jwt.route.authentication.path", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody JwtAuthenticationRequest authenticationRequest, Device device) throws AuthenticationException 

    // Perform the security
    final Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                    authenticationRequest.getUsername(),
                    authenticationRequest.getPassword()
            )
    );
    SecurityContextHolder.getContext().setAuthentication(authentication);

    // Reload password post-security so we can generate token
    final UserDetails userDetails = userDetailsService.loadUserByUsername(authenticationRequest.getUsername());
    final String token = jwtTokenUtil.generateToken(userDetails, device);

    // Return the token
    return ResponseEntity.ok(new JwtAuthenticationResponse(token));

问题似乎出在代码的这个特定部分:

// Perform the security
    final Authentication authentication = authenticationManager.authenticate(
            new UsernamePasswordAuthenticationToken(
                    authenticationRequest.getUsername(),
                    authenticationRequest.getPassword()
            )
    );

当它试图返回对象“UserNamePasswordAuthenticationToken”时,它只是将断点发送到函数“doFilterInternal”的末尾,特别是在调用“chain.doFilter”之后的括号。

【问题讨论】:

【参考方案1】:

问题解决了!显然连续 16 小时编码会影响你的思维方式!

上面的代码没有任何问题,出于某种原因,我将新创建的用户设置为默认禁用!

【讨论】:

以上是关于Spring Boot + Security + JWT 无法生成令牌的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot Security

Understand Spring Security Architecture and implement Spring Boot Security

如何使用 Spring-Boot 播种 Spring-Security

Spring Boot整合Spring Security总结

Spring Boot:整合Spring Security

spring boot 整合spring security中spring security版本升级的遇到的坑