实现JWT token时如何解决@Bean required错误

How to solve the @Bean required error while implementing JWT token

我正在尝试使用 spring 引导进行身份验证 Web API。我已经使用 spring 安全和 JWT 令牌方法来构建这个 API。但在某种程度上我得到了这个错误:

Field jwtUtils in com.example.demo.services.JwtFilterRequest required a bean of type 'com.example.demo.utils.JwtUtils' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.example.demo.utils.JwtUtils' in your configuration.

这是我的 JwtFilterRequest 文件:

package com.example.demo.services;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import com.example.demo.utils.JwtUtils;

@Component
public class JwtFilterRequest extends OncePerRequestFilter {
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private UserService userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String authorizationHeader=request.getHeader("Authorization");
        String username=null;
        String jwtToken=null;
        if(authorizationHeader != null && authorizationHeader.startsWith("Bearer")) {
            jwtToken = authorizationHeader.substring(7);
            username=jwtUtils.extractUsername(jwtToken);
        }
        if(username != null && SecurityContextHolder.getContext().getAuthentication()==null) {
            UserDetails currentUserDetails=userService.loadUserByUsername(username);
            Boolean tokenValidated=jwtUtils.validateToken( jwtToken,currentUserDetails);
            if(tokenValidated) {
                 UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken (currentUserDetails,null);
                 usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                 SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
            }
        }
        filterChain.doFilter(request, response);
    }

}

这是我的 JwtUtils 文件:

package com.example.demo.utils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.security.core.userdetails.UserDetails;

import com.mongodb.Function;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JwtUtils {
    
    private static final String Secret_Key="dsfbhzksbnvrjaehglxkj";
    
    public String generateToken(UserDetails userdetails) {
        Map<String,Object>claims=new HashMap<>();
        return createToken(claims,userdetails.getUsername());
    }
    
    public Boolean validateToken(String token, UserDetails userdetails) {
        String userName=extractUsername(token);
        return userName.equals(userdetails.getUsername()) && !isTokenExpired(token);
        
    }
    
    private String createToken(Map<String, Object>claims,String subject) {
        
        Date now=new Date(System.currentTimeMillis());
        Date util=new Date(System.currentTimeMillis()+1000*60*60*10);
        return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(now).setExpiration(util).signWith(SignatureAlgorithm.HS256, Secret_Key).compact() ;
        
    }
    public <T> T extractClaim(String token, Function <Claims,T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }
    private Claims extractAllClaims(String token) {
        return Jwts.parser().setSigningKey(Secret_Key).parseClaimsJws(token).getBody();
    }
    public String extractUsername(String token) {
        return extractClaim(token,Claims::getSubject);
    }
    public Date extractExpiration (String token) {
        return extractClaim(token,Claims::getExpiration);       
    }
    
    public Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }
    

}

我尝试在该区域添加 @Bean 注释,但它再次抛出错误,指出那里不允许。

添加 @Component 注释到 JwtUtils 以便 Spring 在运行时创建它的 bean,可以注入 JwtFilterRequest.

如果你有任何现有的 class 注释为 @Configuration 那么你可以在 class 中定义 @Bean :

import com.example.demo.utils.JwtUtils;
..
@Configuration
public class Config{
.. // other configs
@Bean
public JwtUtils jwtUtils(){
return new JwtUtils();
}

}