Commit 1d7caf8e authored by Dave Syer's avatar Dave Syer

Man up and deal with CSRF in integration test

Fixes gh-979
parent ed0cfea6
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId> <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
......
...@@ -73,10 +73,6 @@ public class SampleWebSecureApplication extends WebMvcConfigurerAdapter { ...@@ -73,10 +73,6 @@ public class SampleWebSecureApplication extends WebMvcConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
if (!security.isEnableCsrf()) {
// For testing
http.csrf().disable();
}
http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin() http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin()
.loginPage("/login").failureUrl("/login?error").permitAll(); .loginPage("/login").failureUrl("/login?error").permitAll();
} }
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
</fieldset> </fieldset>
<input type="submit" id="login" value="Login" <input type="submit" id="login" value="Login"
class="btn btn-primary" /> <input type="hidden" class="btn btn-primary" /> <input type="hidden"
th:name="${_csrf.parameterName}" th:value="${_csrf.token}" th:if="${_csrf}"/> th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</form> </form>
</div> </div>
</div> </div>
......
...@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull; ...@@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -48,7 +50,7 @@ import org.springframework.util.MultiValueMap; ...@@ -48,7 +50,7 @@ import org.springframework.util.MultiValueMap;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleWebSecureApplication.class) @SpringApplicationConfiguration(classes = SampleWebSecureApplication.class)
@WebAppConfiguration @WebAppConfiguration
@IntegrationTest({ "server.port:0", "security.enable_csrf:false" }) @IntegrationTest("server.port:0")
@DirtiesContext @DirtiesContext
public class SampleSecureApplicationTests { public class SampleSecureApplicationTests {
...@@ -62,14 +64,14 @@ public class SampleSecureApplicationTests { ...@@ -62,14 +64,14 @@ public class SampleSecureApplicationTests {
ResponseEntity<String> entity = new TestRestTemplate().exchange( ResponseEntity<String> entity = new TestRestTemplate().exchange(
"http://localhost:" + this.port, HttpMethod.GET, new HttpEntity<Void>( "http://localhost:" + this.port, HttpMethod.GET, new HttpEntity<Void>(
headers), String.class); headers), String.class);
assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals(HttpStatus.FOUND, entity.getStatusCode());
assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), assertTrue("Wrong location:\n" + entity.getHeaders(),
entity.getBody().contains("<title>Login")); entity.getHeaders().getLocation().toString().endsWith(port + "/login"));
} }
@Test @Test
public void testLogin() throws Exception { public void testLogin() throws Exception {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = getHeaders();
headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
...@@ -86,6 +88,20 @@ public class SampleSecureApplicationTests { ...@@ -86,6 +88,20 @@ public class SampleSecureApplicationTests {
entity.getHeaders().get("Set-Cookie")); entity.getHeaders().get("Set-Cookie"));
} }
private HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
ResponseEntity<String> page = new TestRestTemplate().getForEntity(
"http://localhost:" + this.port + "/login", String.class);
assertEquals(HttpStatus.OK, page.getStatusCode());
String cookie = page.getHeaders().getFirst("Set-Cookie");
headers.set("Cookie", cookie);
Matcher matcher = Pattern.compile("(?s).*name=\"_csrf\".*?value=\"([^\"]+).*").matcher(
page.getBody());
assertTrue("No csrf token: " + page.getBody(), matcher.matches());
headers.set("X-CSRF-TOKEN", matcher.group(1));
return headers;
}
@Test @Test
public void testCss() throws Exception { public void testCss() throws Exception {
ResponseEntity<String> entity = new TestRestTemplate().getForEntity( ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment