【发布时间】:2014-07-30 17:52:18
【问题描述】:
在 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 类型的bean”)。谢谢,我要拔头发了。
我想我只是有点不清楚所有注释的目的。 Spring Boot 参考很好,但它并没有真正超出既定基线。似乎一旦你必须将 spring security、hibernate 和 mvc 结合在一起,它就开始变得复杂,不清楚要做什么。
【问题讨论】:
-
看起来像上下文父子问题。您不能自动装配在父上下文的子上下文中创建的 bean,但反过来也可以
-
谢谢 gerrytan,但我不确定你在说什么
-
这不是父上下文问题,因为只有一个上下文。
标签: spring-mvc spring-security spring-boot