在Spring boot下设置测试环境时,我仍然需要使用各种注释。
我一直指的是this article,它清楚地说明如何处理 Spring Boot 下的各种上下文。剩下的问题是我似乎无法找到一个注释组合,使springSecurityFilterChain
在主应用程序上下文中可见(从此处驱动):
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) throws Exception {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
并从此处开始的测试应用程序上下文中获取:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestPersistenceConfig.class,MvcConfig.class,SecurityConfig.class},loader=AnnotationConfigContextLoader.class)
//@SpringApplicationConfiguration(classes = {TestPersistenceConfig.class,MvcConfig.class,SecurityConfig.class})
@WebAppConfiguration
public class ApplicationIntegrationTest {
MockMvc mockMvc;
@Autowired
private WebApplicationContext wac;
//@Resource(name="springSecurityFilterChain")
@Autowired
private FilterChainProxy springSecurityFilterChain;
@Autowired
private UserDao userDao;
@Autowired
private ClientDao clientDao;
@Autowired
private RoleDao roleDao;
UUID key = UUID.fromString("f3512d26-72f6-4290-9265-63ad69eccc13");
@Before
public void setup() {
// using the web application to initate the mock
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilter(springSecurityFilterChain).build();
// our other choice is using another controller config
//mockMvc = MockMvcBuilders.annotationConfigSetup(ExampleApplicationContext.class).build();
// here we should build up the data structure using hibernate
List<Client> clients = new ArrayList<>();
Client clientEN = new Client();
clientEN.setDeviceId("444444444");
clientEN.setLanguage("en-EN");
clientEN.setAgentId("444444444|68:5b:35:8a:7c:d0");
Client clientENDomain = clientDao.save(clientEN);
clients.add(clientENDomain);
List<Role> roles = new ArrayList<>();
Role roleUser = new Role();
roleUser.setRole("user");
Role roleUserDomain = roleDao.save(roleUser);
roles.add(roleUserDomain);
Role roleAdmin = new Role();
roleAdmin.setRole("admin");
Role roleAdminDomain = roleDao.save(roleAdmin);
roles.add(roleAdminDomain);
User user = new User();
user.setLogin("user");
user.setPassword("password");
user.setClients(clients);
user.setRoles(roles);
userDao.save(user);
}
@Test
public void thatViewBootstrapUsesHttpNotFound() throws Exception {
// testing that a correct login into the form will result in a cookie being set
MvcResult result = mockMvc.perform(post("/login")
.param("username", "user").param("password", "password")).andReturn();
Cookie c = result.getResponse().getCookie("my-cookie");
Cookie[] cookies = result.getResponse().getCookies();
for (int i = 0; i <= cookies.length; i++) {
System.out.println("cookie " + i + " name: " + cookies[i].getName());
System.out.println("cookie " + i + " value: " + cookies[i].getValue());
}
//assertThat(c.getValue().length(), greaterThan(10));
// No cookie; 401 Unauthorized
mockMvc.perform(get("/")).andExpect(status().isUnauthorized());
// With cookie; 200 OK
mockMvc.perform(get("/").cookie(c)).andExpect(status().isOk());
// Logout, and ensure we're told to wipe the cookie
result = mockMvc.perform(delete("/session")).andReturn();
c = result.getResponse().getCookie("my-cookie");
assertThat(c.getValue().length(), is(0));
}
}
顺便说一句@SpringApplicationConfiguration
似乎在任何情况下都不起作用,与doco相反。安全配置如下:
@Configuration
@EnableWebMvcSecurity
@ComponentScan({
"com.touchcorp.touchpoint.security",
"com.touchcorp.touchpoint.service",
"com.touchcorp.touchpoint.model.dao"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DeviceUsernamePasswordAuthenticationProvider customAuthenticationProvider;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(customAuthenticationProvider);
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
@Order(2)
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.failureUrl("/login?error=1")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/");
}
}
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resources/**")
.addResourceLocations("/resources/")
.setCachePeriod(31556926);
}
}
任何人都可以看到为什么springSecurityFilterChain
不可见(“找不到FileterChainProxy
类型的豆子”)。谢谢,我把头发拉出来了。
我认为我对所有注释的目的有点不清楚。 Spring Boot参考是好的,但它并没有真正超出既定的基线。看来,只要你必须将spring security,hibernate和mvc结合在一起,它就会变得复杂起来并且不清楚它是做什么的。
答案 0 :(得分:0)
我会担心@SpringApplicationConfiguration
无法正常工作,因为它在其他地方广泛使用(例如在Spring Boot示例中)并且在那里工作正常。也许是类路径问题?如何链接到其他人可以尝试重现您的问题的完整项目?
您有2个不同的应用程序上下文(一个用于测试,一个用于Application
),因此如果它们表现不同就不足为奇了。特别是Application
有@EnableAutoConfiguration
而你测试(据我们所见)并没有,所以有一个区别是值得研究的。但是测试没有明显的错误。
以下是自动安装过滤器的测试示例:https://github.com/spring-projects/spring-security-oauth/blob/master/samples/oauth2/sparklr/src/test/java/org/springframework/security/samples/config/ApplicationConfigurationTests.java。有用。这是另一个:https://github.com/cloudfoundry/uaa/blob/master/uaa/src/test/java/org/cloudfoundry/identity/uaa/mock/audit/AuditCheckMvcMockTests.java。
答案 1 :(得分:0)
感谢Dave Syer,
我做了一些似乎可以解决各种缺失部分的更改:
以以下开头的测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestApplicationConfig.class,TestPersistenceConfig.class,MvcConfig.class,SecurityConfig.class},loader=AnnotationConfigWebContextLoader.class)
@WebAppConfiguration
public class ApplicationIntegrationTest {
和&#34;标记&#34; Config类,用作组件扫描程序:
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = {"com.touchcorp.touchpoint"})
public class TestApplicationConfig {
}
所有的分析似乎都在数据层之外,它找不到我的任何域对象,但这似乎仅限于JPA / Hibernate配置,而不是应用程序问题。
再次感谢。