Reputation: 271
I have the following code:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
<title>Fileupload Test</title>
</head>
<body>
<p th:text="${msg}"></p>
<form action="#" th:action="@{/fileUpload}" method="post" enctype="multipart/form-data">
<input type="file" name="myFile"/>
<input type="submit"/>
</form>
</body>
</html>
I get the error HTTP 403:
Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'
CSRF is working if I use this line instead:
<form action="#" th:action="@{/fileUpload} + '?' + ${_csrf.parameterName} + '=' + ${_csrf.token}" method="post" enctype="multipart/form-data">
But how can I achieve working CSRF if I use headers?
Upvotes: 19
Views: 12006
Reputation: 1000
After fighting with this issue for some time, I finally figured out why the code in the official Spring documentation doesn't work... Notice the following:
<meta name="_csrf" content="${_csrf.token}" />
<meta name="_csrf_header" content="${_csrf.headerName}" />
This is documentation with JSP in mind! Since we are using Thymeleaf, what you need to do is to use th:content
instead of content
:
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
Now it works!
Upvotes: 26
Reputation: 177
<!DOCTYPE html><html xmlns:th="http://www.thymeleaf.org"><head>
<meta name="_csrf" th:content="${_csrf.token}"/>
<!-- default header name is X-CSRF-TOKEN -->
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>
and
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$.ajax({
url: url,
method: 'DELETE',
success: function(result) {
$('#table').bootstrapTable('remove', {
field: 'id',
values: [row.id]
});
},
error:function(result) {
console.log(result);
}
});
Solved a problem with jquery ajax request delete .I use Spring Boot , Security and bootstrap -table .
Upvotes: 8
Reputation: 8434
Personally using same configuration as you (Thymleaf, Spring MVC, Spring Sec) i only was able to utilise meta csrf when uploading via ajax and direct inserts into action URL if submitting in standard fashion. So different types of forms used:
e.g.
<form action="#" th:action="@{/fileUpload} + '?' + ${_csrf.parameterName} + '=' + ${_csrf.token}" method="post" enctype="multipart/form-data">
for Standard submition
<form action="#" th:action="@{/fileUpload}" method="post" enctype="multipart/form-data">
with following javascript:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
to submit via Ajax/jQuery.
Based on my recent research there doesn't seem to be a clean integration between the two and requires slight modifications to make code work.
Upvotes: 3