Spring Boot测试:无法在Test Class上自动装配springSecurityFilterChain

时间:2014-06-10 04:43:29

标签: spring-mvc spring-security spring-boot

在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结合在一起,它就会变得复杂起来并且不清楚它是做什么的。

2 个答案:

答案 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配置,而不是应用程序问题。

再次感谢。