Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing security in Spring Boot 1.4

I'm trying to test @WebMvcTest with custom security settings defined in SecurityConfig class:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/admin*").access("hasRole('ADMIN')").antMatchers("/**").permitAll().and().formLogin();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("password").roles("ADMIN");
    }
}

Test class is:

@RunWith(SpringRunner.class)
@WebMvcTest(value = ExampleController.class)
public class ExampleControllerMockMVCTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void indexTest() throws Exception {
        mockMvc.perform(get("/"))
        .andExpect(status().isOk())
        .andExpect(view().name("index"));
    }

    @Test
    public void adminTestWithoutAuthentication() throws Exception {
        mockMvc.perform(get("/admin"))
        .andExpect(status().is3xxRedirection()); //login form redirect
    }

    @Test
    @WithMockUser(username="example", password="password", roles={"ANONYMOUS"})
    public void adminTestWithBadAuthentication() throws Exception {
        mockMvc.perform(get("/admin"))
        .andExpect(status().isForbidden());
    }

    @Test
    @WithMockUser(username="user", password="password", roles={"ADMIN"})
    public void adminTestWithAuthentication() throws Exception {
        mockMvc.perform(get("/admin"))
        .andExpect(status().isOk())
        .andExpect(view().name("admin"))
        .andExpect(model().attributeExists("name"))
        .andExpect(model().attribute("name", is("user")));
    }
}

Tests fail because they are using the default security settings of Spring Boot.

I can fix this using @SpringBootTest + @AutoConfigureMockMvc, but it would be interesting to test without running all auto-configuration.

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class ExampleControllerSpringBootTest {

    @Autowired
    private MockMvc mockMvc;

    // tests
}

Is there any way that @WebMvcTest can use settings defined in SecurityConfig class?

like image 254
dmunozfer Avatar asked Jul 30 '16 14:07

dmunozfer


People also ask

How do I ensure security in spring boot?

For adding a Spring Boot Security to your Spring Boot application, we need to add the Spring Boot Starter Security dependency in our build configuration file. Maven users can add the following dependency in the pom. xml file. Gradle users can add the following dependency in the build.

What is the difference between SpringJUnit4ClassRunner and SpringRunner?

There is no difference, from the javadoc: SpringRunner is an alias for the SpringJUnit4ClassRunner. Save this answer.


1 Answers

WebMvcTest is only going to load your controller and nothing else (that's why we call that slicing). We can't figure out which part of your configuration you want and which one you don't. If the security config isn't on your main @SpringBootApplication you'll have to import it explicitly. Otherwise, Spring Boot is going to enable default security settings.

If you're using something like OAuth, that's a good thing though because you really don't want to start using that for a mock test. What happens if you add @Import(SecurityConfig.class) to your test?

like image 197
Stephane Nicoll Avatar answered Oct 13 '22 17:10

Stephane Nicoll