when I try to run test cases I keep running to this issue. Can't figure out what is going on. Any help, please? Thank you.
Message:
N/A
Stack trace:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through field 'jwtTokenProvider'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.utopia.auth.jwk.JwtTokenProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.utopia.auth.jwk.JwtTokenProvider' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
... 89 more
enter code here
This is my config file, Seems like error happening here bases on stacktrace.
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
.anyRequest().fullyAuthenticated()
.and()
.logout().permitAll()
.logoutRequestMatcher(new AntPathRequestMatcher("/api/user/logout", "POST"))
.and()
.formLogin().loginPage("/auth/login").and()
.httpBasic().and()
.csrf().disable();
//jwt filter
http.addFilter(new JWTAuthorizationFilter(authenticationManager(),jwtTokenProvider));
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
//Cross origin resource sharing.
@Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
}
};
}
}
And acutal JWTProvider file
@Component
public class JwtTokenProvider {
@Value("${app.jwt.secret}")
private String jwtSecret;
@Value("${app.jwt.token.prefix}")
private String jwtTokenPrefix;
@Value("${app.jwt.header.string}")
private String jwtHeaderString;
@Value("${app.jwt.expiration-in-ms}")
private Long jwtExpirationInMs;
public String generateToken(Authentication auth) {
String authorities = auth.getAuthorities().stream().map(GrantedAuthority::getAuthority)
.collect(Collectors.joining());
return Jwts.builder().setSubject(auth.getName()).claim("roles", authorities)
.setExpiration(new Date(System.currentTimeMillis() + jwtExpirationInMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret).compact();
}
public Authentication getAuthentication(HttpServletRequest request) {
String token = resolveToken(request);
if (token == null) {
return null;
}
Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody();
String username = claims.getSubject();
final List<GrantedAuthority> authorities = Arrays.stream(claims.get("roles").toString().split(","))
.map(role -> role.startsWith("ROLE_") ? role : "ROLE_" + role).map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
return username != null ? new UsernamePasswordAuthenticationToken(username, null, authorities) : null;
}
public boolean validateToken(HttpServletRequest request) {
String token = resolveToken(request);
if (token == null) {
return false;
}
Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody();
if (claims.getExpiration().before(new Date())) {
return false;
}
return true;
}
private String resolveToken(HttpServletRequest req) {
// Bearer key...
String bearerToken = req.getHeader(jwtHeaderString);
if (bearerToken != null && bearerToken.startsWith(jwtTokenPrefix)) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
}
Honestly I dont understand exactly what Spring is complatining about. Been looking debuging it for past 4 hours, still nothing. (
One possible reason is that Spring is not picking it up in its default component scan. By default, Spring will only for package under the top SpringApplication class with the main method.
So if you SpringApplication is located: my.app.pkg.SpringApplication.java
Other classes in my.app.pkg will not automatically autowire. You can move then to a package below: my.app.pkg.abc
You can also use the @ComponentScan(...) annotation and list all the packages with spring components.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.