当前位置: 首页 > 知识库问答 >
问题:

无法调用扩展(JWT)OncePerRequestFilter。因为@Autowire正在失败,所以这个。类返回null

梁丘宏硕
2023-03-14

我目前正在构建一个标准的JwtAuthorizationFilter。为此,我扩展了OncePerRequestFilter类。此外,我还有一个JwtUtils类,它包含所有JWT方法。例如,一种方法验证JWT承载令牌。然而,我不断得到这样一个错误:这个方法(以及所有其他方法)无法调用,因为this。jwtUtils为空。

因此,我尝试autowireJwtUtils类。但是Spring没有给出任何实例。相反,它给出了null

这是我的错误信息

Cannot invoke ... jwt.JwtUtils.validateJwtToken(String)" because "this.jwtUtils" is null

JwtAuthorizationFilter类(此处抛出错误)

@Slf4j
public class JwtAuthorizationFilter extends OncePerRequestFilter {

  @Autowired private JwtUtils jwtUtils;
  @Autowired private UserDetailsServiceImpl userDetailsService;

  @Override
  protected void doFilterInternal(
          HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws ServletException, IOException {
    try {
      String jwt = JwtUtils.resolveToken(request);
      System.out.println("before if " + jwt);
      if (jwtUtils.validateJwtToken(jwt)) { // ERROR !
        String username = jwtUtils.getUserNameFromJwtToken(jwt);
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        UsernamePasswordAuthenticationToken authentication =
            new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

        SecurityContextHolder.getContext().setAuthentication(authentication);
      }

    } catch (Exception e) {
      JwtAuthorizationFilter.log.error("Cannot set user authentication: {}", e.getMessage());
    }
    filterChain.doFilter(request, response);
  }
}

JwtUtils类

import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Slf4j
@Component
public class JwtUtils {

  @Value("${ggg.app.jwtSecret}")
  private String jwtSecret;

  @Value("${ggg.app.jwtExpirationMs}")
  private long jwtExpirationMs;

  @Value("${ggg.app.jwtRefreshExpirationMs}")
  private long jwtRefreshExpirationMs;

  static String resolveToken(HttpServletRequest req) {
    String bearerToken = req.getHeader("Authorization");
    if (bearerToken != null && bearerToken.startsWith("Bearer ")) return bearerToken.substring(7);
    return null;
  }

  public String generateJwtAccessToken(String username) {
    return generateTokenFromUsername(username, jwtExpirationMs);
  }

  public String generateJwtRefreshToken(String username) {
    return generateTokenFromUsername(username, jwtRefreshExpirationMs);
  }

  private String generateTokenFromUsername(String username, Long expiration) {
    return Jwts.builder()
        .setSubject(username)
        .setIssuedAt(new Date())
        .setExpiration(new Date((new Date()).getTime() + expiration))
        .signWith(secretKey())
        .compact();
  }

  public String getUserNameFromJwtToken(String token) {
    return Jwts.parserBuilder()
        .setSigningKey(secretKey())
        .build()
        .parseClaimsJws(token)
        .getBody()
        .getSubject();
  }

  public boolean validateJwtToken(String token) {
    try {
      Jwts.parserBuilder().setSigningKey(secretKey()).build().parseClaimsJws(token);
      return true;
    } catch (SignatureException e) {
      JwtUtils.log.error("Invalid JWT signature: {}", e.getMessage());
    } catch (MalformedJwtException e) {
      JwtUtils.log.error("Invalid JWT token: {}", e.getMessage());
    } catch (ExpiredJwtException e) {
      JwtUtils.log.error("JWT token is expired: {}", e.getMessage());
    } catch (UnsupportedJwtException e) {
      JwtUtils.log.error("JWT token is unsupported: {}", e.getMessage());
    } catch (IllegalArgumentException e) {
      JwtUtils.log.error("JWT claims string is empty: {}", e.getMessage());
    }
    return false;
  }

  private SecretKey secretKey() {
    return Keys.hmacShaKeyFor(jwtSecret.getBytes());
  }
}

网络安全配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Autowired private UserDetailsServiceImpl userDetailsService;

  @Bean
  private static PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12);
  }

  @Bean
  private static JwtAuthorizationFilter authenticationJwtTokenFilter() {
    return new JwtAuthorizationFilter();
  }

  //  @Override
  //  public void configure(AuthenticationManagerBuilder authenticationManagerBuilder)
  //      throws Exception {
  //    authenticationManagerBuilder
  //        .userDetailsService(userDetailsService)
  //        .passwordEncoder(WebSecurityConfig.passwordEncoder());
  //  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {

    // Disable CSRF (cross site request forgery)
    http.cors()
        .and()
        .csrf()
        .disable()
        // No session will be created or used by spring security
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests()
        .antMatchers("/api/v1/auth/**", "/confirm-account")
        .permitAll()
        .anyRequest()
        .authenticated();

    // Apply JWT
    http.addFilterBefore(
        WebSecurityConfig.authenticationJwtTokenFilter(),
        UsernamePasswordAuthenticationFilter.class);
  }
}

问题解决者?

 @Bean
  public JwtAuthorizationFilter authenticationJwtTokenFilter() {
    return new JwtAuthorizationFilter();
  }

我发现私有静态JwtAuthorizationFilter身份验证JwtTokenFilter()方法正在调用该问题。如果我将其更改为公共方法,它正在工作。不幸的是,是我的插件导致了这个问题。它会自动更改代码。有人知道该怎么办吗?


共有1个答案

皇甫文乐
2023-03-14

这是因为JwtUtils和WebSecurityConfig没有注册为Spring Beans。请尝试向类添加@Component注释。

有关Spring Boot中依赖项注入的更多信息:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.spring-bean和依赖注入

 类似资料:
  • 好的,我看过很多关于这个的帖子,我花了一整天的时间来解决这个问题,但是没有成功。 我试图创建一个Laravel项目。我使用的是Mac(优胜美地),它运行PHP 5.5.14。机器上还有一个较旧版本的PHP。当我尝试使用“laravel new project ectname”从命令行创建项目时,没有报告错误,但是命令只创建了一个名为项目名称的空文件夹。我得到了“制作应用程序......”和“应用程

  • 我们有一个公司范围的Nexus 3服务器 拥有我们自己的文物和 用作Maven Central和其他回购的代理。 开发人员使用两个存储库: maven针对所有已发布/稳定的工件发布版本策略“Release”和 版本策略为“快照”的所有快照工件的maven快照 这两个存储库都用于Gradle构建: 现在,当Gradle试图解决快照依赖关系时,它会询问releases存储库,Nexus会用 而构建失败

  • clarations -std=c++11 -c /tmp/swoole-4.8.6/src/protocol/websocket.cc -fPIC -DPIC -o src/protocol/.libs/websocket.o Assembler messages: Error: can't open /tmp/ccz3gtNM.s for reading: No such file or di

  • 我正试图用Gradle创建一个Fat/Uber罐子。不幸的是,我一直遇到以下错误: 我试图删除我的缓存目录,认为也许有些东西被破坏了,但仍然没有快乐。 建筑gradle文件: 我尝试过使用shadowJar插件,但这导致依赖项没有包含在胖jar中。关于这个问题,我有一个单独的问题。目前,我正在使用Maven,它完美地构建了一个胖罐子。

  • 问题内容: 我有以下表格- 对于这些表,关联的Dao和DaoImpl如下 数据库助手如下: 现在,当我尝试致电- 它错误并显示以下错误: 现在,如果我在A中没有foreign键-即如果A不包含 公共B b ,那么它可以正常工作。我在这里缺少什么吗? 提前非常感谢您。 问题答案: 我怀疑在异常堆栈跟踪的末尾有您丢失的原因消息。例如,如果我在上面重复了您的示例,则会得到: 因为有一个class的外部字