I have spring boot application. I want create two profiles for SecurityConfig: dev, prod. First attempt was with two classes extends from WebSecurityConfigurerAdapter, but than I create two Beans within SecurityConfig class. My Configuration looks like this:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig {
@Bean
public JwtAuthorizeFilter jwtAuthenticationFilter() throws Exception {
return new JwtAuthorizeFilter();
}
@Bean
@Profile("prod")
public WebSecurityConfigurerAdapter prod() {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
//some code...
}
};
}
@Bean
@Profile("dev")
public WebSecurityConfigurerAdapter dev() {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
//some code...
}
};
}
@Bean
public WebMvcConfigurer corsConfig() {
return new WebMvcConfigurerAdapter() {
//some code...
};
}
}
Also class for run application:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
System.setProperty("spring.profiles.active", "dev");
SpringApplication.run(Application.class, args);
}
}
How can I test that correct profiles is active when I will start application? When I add empty test
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("dev")
@ContextConfiguration(classes = SecurityConfig.class, loader=AnnotationConfigContextLoader.class)
public class SpringProfileConfigurationTest {
@Autowired
public WebSecurityConfigurerAdapter securityConfig;
@Test
public void testSecurityConfigDevActiveProfile() {
}
}
It is fall down with error:
.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework .security.config.annotation.web.configuration.WebSecurityConfigurerAdapter' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:{@org.springframework.beans.factory.annotation .Autowired(required=true)}
UPD: add "classes" to @ContextConfiguration, and than another error:
BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtAuthenticationFilter': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.core.userdetails.UserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
So the problem now is in org.springframework.security.core.userdetails.UserDetailsService - It can't be Autowired. It is used in
@Component
public class JwtAuthorizeFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
//some code;
}
In order to add Security Bean to your test, add
SecurityConfigto your ContextConfiguration definition