PROBLEM
With Spring Security 4.x, the CSRF protection is enabled by default. You may disable it, but to be more aligned with OWASP and the industry security standard, it’s best to leave this setting the way it is. Learn more about CSRF attack…
To prevent this attack, Spring Security 4.x requires you to attach a server-side generated CSRF token on any POST, PUT or DELETE calls… basically, actions that may modify the request state. Their argument for not attaching this token on GET is to prevent this token value from leaking out.
Further, you will require to call POST /login and POST /logout now. In the past, you can call GET /j_spring_security_logout without problem.
If you invoke POST, PUT or DELETE without this CSRF token, you will get a 403 error with this message: “Invalid CSRF Token ‘null’ was found on the request parameter ‘_csrf’ or header ‘X-CSRF-TOKEN’.”.
SOLUTION
To obtain this CSRF token, add this Spring Security custom tag to the JSP file:-
<!DOCTYPE html>
<html>
<head>
<sec:csrfMetaTags/>
</head>
<body>
</body>
</html>
The rendered HTML looks like this:-
<!DOCTYPE html>
<html class="no-js">
<head>
<meta name="_csrf_parameter" content="_csrf" />
<meta name="_csrf_header" content="X-CSRF-TOKEN" />
<meta name="_csrf" content="e62835df-f1a0-49ea-bce7-bf96f998119c" />
</head>
<body>
</body>
</html>
Finally, set the request header before making the AJAX call:-
var header = $("meta[name='_csrf_header']").attr("content");
var token = $("meta[name='_csrf']").attr("content");
$.ajax({
url: '/test',
type: 'POST',
beforeSend: function(xhr){
xhr.setRequestHeader(header, token);
},
success: function(data) {
console.log(data);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status + ": " + thrownError);
}
});
Leave a Reply