我正在尝试在我的REST API中对登录和安全性进行单元测试,因此我尝试尽可能接近地模拟现实生活中的请求序列.
我的第一个请求是:
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).
addFilters(springSecurityFilterChain).build();
this.mapper = new ObjectMapper();
....
MvcResult result=mockMvc.perform(get("/login/csrf")).andExpect(status().is(200)).andReturn();
Cookie[] cookies = result.getResponse().getCookies();
Run Code Online (Sandbox Code Playgroud)
(参见关于pastebin的完整课程).
我尝试在这里获取cookie以便稍后能够使用收到的CSRF令牌登录,但是cookies数组是空的!
但是,如果我运行我的应用程序并打电话
curl -i http://localhost:8080/login/csrf
Run Code Online (Sandbox Code Playgroud)
我确实得到了一个Set-Cookie标头,可以稍后使用该cookie(以及CSRF令牌)进行身份验证.
所以问题是:我如何让MockMvc向我返回一个cookie?
我有一个使用Spring MVC创建的非常简单的REST应用程序.(代码可在GitHub上获得.)它有WebSecurityConfigurer如下简单:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
.csrf().disable()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.authorizeRequests()
.antMatchers("/user/new").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.and()
.logout()
.permitAll()
.logoutSuccessHandler(logoutSuccessHandler);
}
Run Code Online (Sandbox Code Playgroud)
当我运行应用程序时,自定义控制器和登录/注销页面都可以正常运行.我甚至可以通过单元测试 .但是,当我尝试使用以下功能进行测试时/user/newMockMvc/login
@Test
public void testUserLogin() throws Exception {
RequestBuilder requestBuilder = post("/login")
.param("username", testUser.getUsername())
.param("password", testUser.getPassword());
mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk())
.andExpect(cookie().exists("JSESSIONID"));
}
Run Code Online (Sandbox Code Playgroud)
它失败如下:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /login
Parameters = {username=[test-user-UserControllerTest], password=[test-user-UserControllerTest-password]}
Headers = {}
Handler:
Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler
Async: …Run Code Online (Sandbox Code Playgroud) 我为我的春季启动应用程序创建了自定义登录表单.在我的表单集成测试中,我想检查收到的cookie是否包含JSESSIONID和XSRF-TOKEN.
但是,我只收到了XSRF-TOKEN.
这是我的测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
public class UserIT {
@Autowired
private WebApplicationContext context;
@Autowired
private FilterChainProxy springSecurityFilterChain;
@Value("${local.server.port}")
private Integer port;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc =
MockMvcBuilders.webAppContextSetup(context).addFilters(springSecurityFilterChain)
.build();
}
@Test
public void getUserInfoTest() throws Exception {
disableSslVerification();
MvcResult result =
mockMvc.perform(formLogin("/login").user("roy").password("spring")).andExpect(authenticated())
.andReturn();
Cookie sessionId = result.getResponse().getCookie("JSESSIONID");
Cookie token = result.getResponse().getCookie("XSRF-TOKEN");
}
Run Code Online (Sandbox Code Playgroud)
安全配置:
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
//.httpBasic()
//.and() …Run Code Online (Sandbox Code Playgroud) 当我尝试在Spring 4.x上测试时,我使用了MockMvc Web客户端,但我正在阅读并尝试Spring 5.x的新功能.
我认为,WebTestClient和MockMvc是相同或非常相似的.
MockMvc和WebTestClient有什么区别?
我在等待你的回答.谢谢