【发布时间】:2015-08-16 15:43:04
【问题描述】:
我的 Spring Boot 应用程序有一个 Application 类。当我运行它(作为应用程序)时,它会在一个嵌入式 servlet 容器(在我的例子中是 Tomcat)中启动它自己。不知何故(通过应用程序的@annotations,我想),加载了同一个包中的 WebSecurityConfig(扩展 WebSecurityConfigurerAdapter)。
WebSecurityConfig 包含两个重要的配置信息块:
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true) // enables method-level role-checking
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userSearchBase("CN=Users,DC=some,DC=domain,DC=com")
.userSearchFilter("(sAMAccountName={0})")
.groupSearchBase("OU=Groups,DC=some,DC=domain,DC=com")
.groupSearchFilter("(member={0})")
.contextSource()
.managerDn("cn=ad-bind,cn=users,dc=some,dc=domain,dc=com")
.managerPassword("APASSWORD!")
.url("ldaps://some.domain.com:636");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("***************** WebSecurityConfig.configure *************************");
http.csrf().disable();
http
.headers()
.frameOptions()
.disable();
http
.authorizeRequests()
.antMatchers("/resources/images/*", "/me", "/products", "/product/**", "/offerings", "/offering/**", "/client/**")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").defaultSuccessUrl("/me")
.permitAll()
.and()
.logout()
.permitAll();
http.logout().logoutSuccessUrl("/me");
}
}
configureGlobal() 包含我们内部 LDAP 系统的配置,它工作得很好。
configure() 指定哪些 URL 是公开的,哪些只显示给已登录的用户,以及在用户登录时将其发送到哪些相对 URL。
现在我开始进行集成测试,并编写了一些方法来测试不需要身份验证的控制器。这些测试按预期工作。 Application 类启动并针对它执行测试。
但现在我想测试需要身份验证的控制器方法。我认为实现这一点的方法是告诉测试类启动一个替代应用程序类(在我的例子中是 TestApplication)和创建虚拟用户的 WebSecurityConfig:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class) // fires up with TestApplication.class instead of Application.class
@WebAppConfiguration
public class ProductControllerTests {
// test methods here, this time with username/password included
}
@Configuration
@EnableAutoConfiguration
public class TestApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
private static Class<TestApplication> applicationClass = TestApplication.class;
}
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("testuser").password("userpass").roles("USER");
auth.inMemoryAuthentication().withUser("testadmin").password("adminpass").roles("ADMIN");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
System.out.println("***************** WebSecurityConfig.configure *************************");
http.csrf().disable();
http
.headers()
.frameOptions()
.disable();
http
.authorizeRequests()
.antMatchers("/resources/images/*", "/me", "/products", "/product/**", "/offerings", "/offering/**", "/client/**")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").defaultSuccessUrl("/me")
.permitAll()
.and()
.logout()
.permitAll();
http.logout().logoutSuccessUrl("/me");
}
}
所以我的问题是:当我执行单元测试类时,我相信 TestApplication 正在触发。但是,它没有选择替代的 WebSecurityConfig 类及其 auth.inMemoryAuthentication() 测试用户。 如何强制我的应用程序在正常运行应用程序时使用一个 WebSecurityConfig,但在运行单元测试时使用不同的 WebSecurityConfig?
【问题讨论】:
标签: java spring spring-mvc spring-security spring-boot