以下测试失败,因为它返回的是登录页面,而不是内容。
TestRestTemplate restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> form = new LinkedMultiValueMap<>();
form.set("username", testUser.getUser().getUid());
form.set("password", testUser.getUserPassword());
ResponseEntity<String> loginEntity = restTemplate.exchange(
url("/login"),
HttpMethod.POST,
new HttpEntity<>(form, headers),
String.class);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(MediaType.TEXT_HTML));
requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
//
// auth csrf and form login - doesn't work
ResponseEntity<String> getLoginEntity = restTemplate.getForEntity(url("/login"), String.class);
String cookie = getLoginEntity.getHeaders().getFirst(HttpHeaders.SET_COOKIE);
// contains CSRF-TOKEN
requestHeaders.set(HttpHeaders.COOKIE, cookie);
Pattern pattern = Pattern.compile("(?s).*name=\"_csrf\".*?value=\"([^\"]+).*");
Matcher matcher = pattern.matcher(getLoginEntity.getBody());
matcher.matches();
requestHeaders.set("X-CSRF-TOKEN", matcher.group(1));
//
ResponseEntity<String> memberEntity = restTemplate.exchange(
url("/members"),
HttpMethod.GET,
new HttpEntity<>(form, requestHeaders),
String.class
);
assertEquals("Unexpected member content", "Welcome member!", memberEntity.getBody());
配置就像这样
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().and()
.authorizeRequests()
.antMatchers("/**").fullyAuthenticated()
.and()
.formLogin()
.permitAll();
}
返回的登录页面包括_csrf作为隐藏字段,并且该值对应于cookie中已设置的值。
请注意,通过较小的修改,我可以使以下方案起作用:
但是,我没有成功
任何有关如何使其正常工作的指导都将受到赞赏。
答案 0 :(得分:0)
这不起作用,因为您需要cookie和csrf才能进行POST才能登录,因此至少需要发出两个请求。
首先,您需要设置一个暴露csrf令牌的/csrf
页面,例如: {"token": "b3c7338e-95c0-4088-9fb7-d72a870bd60c", "headerName": "X-CSRF-TOKEN", "parameterName": "_csrf" }
然后流程如下:
token
中读取/csrf
,其中还存储 通过标头Set-Cookie
传递的cookie token
指定的名称在请求标头中设置/csrf
,例如:X-CSRF-TOKEN: b3c7338e-95c0-4088-9fb7-d72a870bd60c
Cookie
中设置存储的cookie(这是因为cookie和csrf令牌在服务器上绑定在一起)/login
,存储带有响应标头Set-Cookie
传递给您的cookie(登录后会更改)/login
获取的cookie设置在请求标头Cookie
中token
获得新的/csrf
(因为cookie更改了,令牌也更改了)