If you wish to set up Spring Security in a MockMvc test, you can write this test next to our previous test:
package masterSpringMvc.user.api; import masterSpringMvc.MasterSpringMvcApplication; import masterSpringMvc.user.User; import masterSpringMvc.user.UserRepository; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.security.web.FilterChainProxy; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import java.util.Base64; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MasterSpringMvcApplication.class) @WebAppConfiguration public class UserApiControllerAuthTest { @Autowired private FilterChainProxy springSecurityFilter; @Autowired private WebApplicationContext wac; @Autowired private UserRepository userRepository; private MockMvc mockMvc; @Before public void setup() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).addFilter(springSecurityFilter).build(); userRepository.reset(new User("[email protected]")); } @Test public void unauthenticated_cannot_list_users() throws Exception { this.mockMvc.perform( get("/api/users") .accept(MediaType.APPLICATION_JSON) ) .andExpect(status().isUnauthorized()); } @Test public void admin_can_list_users() throws Exception { this.mockMvc.perform( get("/api/users") .accept(MediaType.APPLICATION_JSON) .header("Authorization", basicAuth("admin", "admin")) ) .andExpect(status().isOk()); } private String basicAuth(String login, String password) { byte[] auth = (login + ":" + password).getBytes(); return "Basic " + Base64.getEncoder().encodeToString(auth); } }
In the preceding example, we added SpringSecurityFilter
to our configuration. This will activate Spring Security checks. To test if the authentication works, we simply send the correct headers along with the request we would like to perform.
The advantage of basic authentication is that it's really straightforward to simulate. With a more complicated setup, you would have to perform a mock request on the authentication endpoint.
At the time of writing, Spring Boot is at version 1.2.3 and depends on Spring Security 3.
In a few weeks, Spring Boot 1.3.0 will be available, it will update Spring Security and use version 4.
This is good news because Spring Security 4 includes a really easy setup of the authenticated user with simple annotations. See http://docs.spring.io/spring-security/site/docs/4.0.x/reference/htmlsingle/#test for more details.