BAEL-797 removing csrf protections

This commit is contained in:
tschiman 2017-05-14 22:24:05 -06:00
parent be4b206478
commit e193a60dc6
6 changed files with 23 additions and 196 deletions

View File

@ -1,15 +1,11 @@
package com.baeldung.spring.cloud.bootstrap.gateway; package com.baeldung.spring.cloud.bootstrap.gateway;
import com.baeldung.spring.cloud.bootstrap.gateway.filter.CsrfHeaderFilter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfFilter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
@EnableWebSecurity @EnableWebSecurity
@Configuration @Configuration
@ -27,8 +23,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
http http
.formLogin() .formLogin()
.loginPage("/login.html")
.loginProcessingUrl("/login")
.defaultSuccessUrl("/home/index.html", true) .defaultSuccessUrl("/home/index.html", true)
.and() .and()
.authorizeRequests() .authorizeRequests()
@ -39,13 +33,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.and() .and()
.logout() .logout()
.and() .and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class) .csrf().disable();
.csrf().csrfTokenRepository(csrfTokenRepository());
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
} }
} }

View File

@ -1,29 +0,0 @@
package com.baeldung.spring.cloud.bootstrap.gateway.filter;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.WebUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CsrfHeaderFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrfToken = (CsrfToken) httpServletRequest.getAttribute(CsrfToken.class.getName());
if (csrfToken != null) {
Cookie cookie = WebUtils.getCookie(httpServletRequest, "XSRF-TOKEN");
String token = csrfToken.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
httpServletResponse.addCookie(cookie);
}
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}

View File

@ -7,6 +7,6 @@
<body> <body>
<h1>Book Rater</h1> <h1>Book Rater</h1>
<p>So many great things about the books</p> <p>So many great things about the books</p>
<a href="/login.html">Login</a> <a href="/login">Login</a>
</body> </body>
</html> </html>

View File

@ -1,65 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form id="loginForm">
<label>Username:</label>
<input id="username" type="text" name="username"/>
<label>Password:</label>
<input id="password" type="password" name="password"/>
<button>Submit</button>
</form>
<script type="text/javascript">
// from stackoverflow: http://stackoverflow.com/questions/5639346/shortest-function-for-reading-a-cookie-in-javascript
(function(){
var cookies;
function readCookie(name,c,C,i){
if(cookies){ return cookies[name]; }
c = document.cookie.split('; ');
cookies = {};
for(i=c.length-1; i>=0; i--){
C = c[i].split('=');
cookies[C[0]] = C[1];
}
return cookies[name];
}
window.readCookie = readCookie; // or expose it however you want
})();
document.getElementById('loginForm').addEventListener('submit', function (e) {
e.preventDefault(); //to prevent form submission
var csrf = window.readCookie("XSRF-TOKEN");
console.log(csrf);
var username = document.getElementById("username").value;
console.log(username);
var password = document.getElementById("password").value;
console.log(password);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/login?' + 'username=' + encodeURIComponent(username) + '&password=' + encodeURIComponent(password));
xhr.setRequestHeader("X-XSRF-TOKEN", csrf);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(null);
xhr.onreadystatechange = function () {
var DONE = 4;
var OK = 200;
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
window.location.replace(xhr.responseURL)
} else {
console.log(xhr);
}
}
}
});
</script>
</body>
</html>

View File

@ -2,9 +2,8 @@ package com.baeldung.spring.cloud.bootstrap.gateway;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.restassured.RestAssured; import io.restassured.RestAssured;
import io.restassured.authentication.FormAuthConfig;
import io.restassured.config.RedirectConfig; import io.restassured.config.RedirectConfig;
import io.restassured.config.SessionConfig;
import io.restassured.filter.session.SessionFilter;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
import io.restassured.response.Response; import io.restassured.response.Response;
import org.junit.Assert; import org.junit.Assert;
@ -17,13 +16,12 @@ import static io.restassured.RestAssured.config;
public class LiveTest { public class LiveTest {
private final String ROOT_URI = "http://localhost:8080"; private final String ROOT_URI = "http://localhost:8080";
SessionFilter sessionFilter; private final FormAuthConfig formConfig = new FormAuthConfig("/login", "username", "password");
@Before @Before
public void setup() { public void setup() {
RestAssured.config = config() RestAssured.config = config().redirect(RedirectConfig.redirectConfig()
.redirect(RedirectConfig.redirectConfig().followRedirects(false)) .followRedirects(false));
.sessionConfig(new SessionConfig().sessionIdName("SESSION"));
} }
@Test @Test
@ -35,28 +33,26 @@ public class LiveTest {
@Test @Test
public void whenAccessProtectedResourceWithoutLogin_thenRedirectToLogin() { public void whenAccessProtectedResourceWithoutLogin_thenRedirectToLogin() {
final Response response = RestAssured.get(ROOT_URI + "/rating-service/ratings?bookId=1"); final Response response = RestAssured.get(ROOT_URI + "/home/index.html");
Assert.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode()); Assert.assertEquals(HttpStatus.FOUND.value(), response.getStatusCode());
Assert.assertNotNull(response.getBody()); Assert.assertEquals("http://localhost:8080/login", response.getHeader("Location"));
} }
@Test @Test
public void whenAccessProtectedResourceAfterLogin_thenSuccess() { public void whenAccessProtectedResourceAfterLogin_thenSuccess() {
SessionData sessionData = login("user", "password");
final Response response = RestAssured.given() final Response response = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("user", "password", formConfig)
.get(ROOT_URI + "/rating-service/ratings?bookId=1"); .get(ROOT_URI + "/book-service/books/1");
Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode()); Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode());
Assert.assertNotNull(response.getBody()); Assert.assertNotNull(response.getBody());
} }
@Test @Test
public void whenAccessAdminProtectedResource_thenForbidden() { public void whenAccessAdminProtectedResource_thenForbidden() {
SessionData sessionData = login("user", "password");
final Response response = RestAssured.given() final Response response = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("user", "password", formConfig)
.get(ROOT_URI + "/rating-service/ratings"); .get(ROOT_URI + "/rating-service/ratings");
Assert.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode()); Assert.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode());
@ -64,10 +60,9 @@ public class LiveTest {
@Test @Test
public void whenAdminAccessProtectedResource_thenSuccess() { public void whenAdminAccessProtectedResource_thenSuccess() {
SessionData sessionData = login("admin", "admin");
final Response response = RestAssured.given() final Response response = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("admin", "admin", formConfig)
.get(ROOT_URI + "/rating-service/ratings"); .get(ROOT_URI + "/rating-service/ratings");
Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode()); Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode());
Assert.assertNotNull(response.getBody()); Assert.assertNotNull(response.getBody());
@ -75,10 +70,9 @@ public class LiveTest {
@Test @Test
public void whenAdminAccessDiscoveryResource_thenSuccess() { public void whenAdminAccessDiscoveryResource_thenSuccess() {
SessionData sessionData = login("admin", "admin");
final Response response = RestAssured.given() final Response response = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("admin", "admin", formConfig)
.get(ROOT_URI + "/discovery"); .get(ROOT_URI + "/discovery");
Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode()); Assert.assertEquals(HttpStatus.OK.value(), response.getStatusCode());
} }
@ -88,12 +82,10 @@ public class LiveTest {
final Rating rating = new Rating(1L, 4); final Rating rating = new Rating(1L, 4);
SessionData sessionData = login("admin", "admin");
// request the protected resource // request the protected resource
final Response ratingResponse = RestAssured.given() final Response ratingResponse = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("admin", "admin", formConfig)
.and() .and()
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body(rating) .body(rating)
@ -108,12 +100,10 @@ public class LiveTest {
public void whenAddnewBook_thenSuccess() { public void whenAddnewBook_thenSuccess() {
final Book book = new Book("Baeldung", "How to spring cloud"); final Book book = new Book("Baeldung", "How to spring cloud");
SessionData sessionData = login("admin", "admin");
// request the protected resource // request the protected resource
final Response bookResponse = RestAssured.given() final Response bookResponse = RestAssured.given()
.header("X-XSRF-TOKEN", sessionData.getCsrf()) .auth()
.filter(sessionFilter) .form("admin", "admin", formConfig)
.and() .and()
.contentType(ContentType.JSON) .contentType(ContentType.JSON)
.body(book) .body(book)
@ -204,60 +194,4 @@ public class LiveTest {
} }
} }
private SessionData login(String username, String password) {
sessionFilter = new SessionFilter();
Response getLoginResponse = RestAssured.given()
.filter(sessionFilter)
.when()
.get("/login.html")
.then()
.extract()
.response();
String csrfToken = getLoginResponse.cookie("XSRF-TOKEN");
RestAssured.given().log().all().
filter(sessionFilter)
.header("X-XSRF-TOKEN", csrfToken)
.param("username", username)
.param("password", password)
.when()
.post("/login");
Response afterLoginResponse = RestAssured.given()
.filter(sessionFilter)
.when()
.get("/")
.then()
.extract()
.response();
return new SessionData(afterLoginResponse.cookie("XSRF-TOKEN"), sessionFilter.getSessionId());
}
private class SessionData {
private String csrf;
private String session;
public SessionData(String csrf, String session) {
this.csrf = csrf;
this.session = session;
}
public String getCsrf() {
return csrf;
}
public void setCsrf(String csrf) {
this.csrf = csrf;
}
public String getSession() {
return session;
}
public void setSession(String session) {
this.session = session;
}
}
} }