I am trying to send a POST-request to a server that is configured to use Spring Security. When submitting my request, I get a 403 error. This is issue is due to CSRF protection. When disabling CSRF in my Spring Security Configuration, the POST request works fine.
I am using the fetch API to send my POST-request. This allows for specifying the HTTP-header that comes with the body containing my JSON-object that I am trying to POST. I am now trying to add the CSRF token to my HTTP-header. For this purpose, I have added the following two meta-tags to the head-section of my HTML:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
I have then added the following lines to my JavaScript:
const token = document.querySelector('meta[name="_csrf"]').content;
const header = document.querySelector('meta[name="_csrf_header"]').content;
let responsePromise = fetch(
"myEndpoint",
{ method: 'POST', headers: {'Content-Type': 'application/json', header: token}, body: JSON.stringify(myJSON) });
})
I am assuming that Spring Security fills out the content of my CSRF-token. So far the error message still persists though. I think there might be nothing inside my _csrf meta-tag. When logging the content (token and header), I just receive:
${_csrf.headerName}
${_csrf.token}
While I am expecting to see the header name "X-CSRF-Token" and the actual token. So could it be that Spring security does not automatically fill out this content?
======= Update:
My project is a Maven project. I have added the Thymeleaf-dependency to my pom.xml. I don't know much about thymeleaf, but it seemed to be the easiest way to implement the Login mechanism with Spring Security. Anyways, when replacing content
with th:content
in my meta-tags, the header and the token are actually found and will be logged in my console. I am still not able to POST my request though, the 403 remains.
Add 'th' before the attribute for thymeleaf processing
<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>