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?
You can obtain the CSRF using the request attribute named _csrf as outlined in the reference. To add the CSRF to an HTML page, you will need to use JavaScript to obtain the token that needs to be included in the requests.
To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.
In Spring Security, the CSRF tokens are generated per session. When a session starts, a CSRF token is generated. If the session changes or times out, a new CSRF token will be returned by the server. The first GET request fails because we're not authenticated.
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!
<!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 .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With