SEC-3097: Use MockMvc for SecurityMockMVcRequestPostProcessorsCsrfTests

This is necessary because the changes for this issue are going to make
the mocked version of the tests invalid.
This commit is contained in:
Rob Winch 2015-09-01 23:17:11 -05:00
parent a9a5377e4a
commit ea94706319
1 changed files with 88 additions and 48 deletions

View File

@ -17,78 +17,118 @@ package org.springframework.security.test.web.servlet.request;
import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.powermock.api.mockito.PowerMockito.*; import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired;
import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest; import org.springframework.context.annotation.Bean;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.test.web.support.WebTestUtils; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.csrf.DefaultCsrfToken; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.test.context.ContextConfiguration;
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.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
@RunWith(PowerMockRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@PrepareOnlyThisForTest(WebTestUtils.class) @ContextConfiguration
@WebAppConfiguration
public class SecurityMockMvcRequestPostProcessorsCsrfTests { public class SecurityMockMvcRequestPostProcessorsCsrfTests {
@Mock @Autowired
private CsrfTokenRepository repository; WebApplicationContext wac;
private DefaultCsrfToken token;
private MockHttpServletRequest request; MockMvc mockMvc;
@Before @Before
public void setup() { public void setup() {
token = new DefaultCsrfToken("header", "param", "token"); mockMvc = MockMvcBuilders
request = new MockHttpServletRequest(); .webAppContextSetup(wac)
mockWebTestUtils(); .apply(springSecurity())
.build();
} }
@Test @Test
public void csrfWithParam() { public void csrfWithParam() throws Exception {
MockHttpServletRequest postProcessedRequest = csrf().postProcessRequest(request); mockMvc.perform(post("/").with(csrf()))
.andExpect(status().is2xxSuccessful())
assertThat(postProcessedRequest.getParameter(token.getParameterName())) .andExpect(csrfAsParam());
.isEqualTo(token.getToken());
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNull();
} }
@Test @Test
public void csrfWithHeader() { public void csrfWithHeader() throws Exception {
MockHttpServletRequest postProcessedRequest = csrf().asHeader() mockMvc.perform(post("/").with(csrf().asHeader()))
.postProcessRequest(request); .andExpect(status().is2xxSuccessful())
.andExpect(csrfAsHeader());
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isNull();
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isEqualTo(
token.getToken());
} }
@Test @Test
public void csrfWithInvalidParam() { public void csrfWithInvalidParam() throws Exception {
MockHttpServletRequest postProcessedRequest = csrf().useInvalidToken() mockMvc.perform(post("/").with(csrf().useInvalidToken()))
.postProcessRequest(request); .andExpect(status().isForbidden())
.andExpect(csrfAsParam());
assertThat(postProcessedRequest.getParameter(token.getParameterName()))
.isNotEmpty().isNotEqualTo(token.getToken());
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNull();
} }
@Test @Test
public void csrfWithInvalidHeader() { public void csrfWithInvalidHeader() throws Exception {
MockHttpServletRequest postProcessedRequest = csrf().asHeader().useInvalidToken() mockMvc.perform(post("/").with(csrf().asHeader().useInvalidToken()))
.postProcessRequest(request); .andExpect(status().isForbidden())
.andExpect(csrfAsHeader());
assertThat(postProcessedRequest.getParameter(token.getParameterName())).isNull();
assertThat(postProcessedRequest.getHeader(token.getHeaderName())).isNotEmpty()
.isNotEqualTo(token.getToken());
} }
private void mockWebTestUtils() { public static ResultMatcher csrfAsParam() {
spy(WebTestUtils.class); return new CsrfParamResultMatcher();
when(WebTestUtils.getCsrfTokenRepository(request)).thenReturn(repository); }
when(repository.loadToken(request)).thenReturn(token);
when(repository.generateToken(request)).thenReturn(token); static class CsrfParamResultMatcher implements ResultMatcher {
public void match(MvcResult result) throws Exception {
MockHttpServletRequest request = result.getRequest();
assertThat(request.getParameter("_csrf")).isNotNull();
assertThat(request.getHeader("X-CSRF-TOKEN")).isNull();
}
}
public static ResultMatcher csrfAsHeader() {
return new CsrfHeaderResultMatcher();
}
static class CsrfHeaderResultMatcher implements ResultMatcher {
public void match(MvcResult result) throws Exception {
MockHttpServletRequest request = result.getRequest();
assertThat(request.getParameter("_csrf")).isNull();
assertThat(request.getHeader("X-CSRF-TOKEN")).isNotNull();
}
}
@EnableWebSecurity
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
@Bean
public TheController controller() {
return new TheController();
}
@RestController
static class TheController {
@RequestMapping("/")
String index() {
return "Hi";
}
}
} }
} }