With csrf disabled I can upload file however I need it enabled. The problem only occurs when the form enctype is multipart/form-data, namely 'Invalid CSRF Token' with 403.
Generally when I set the enctype as multipart/form-data even for a form without file upload, I get the same error.
Using this dependency:
<dependency>
<groupId>org.synchronoss.cloud</groupId>
<artifactId>nio-multipart-parser</artifactId>
<version>...</version>
</dependency>
Tried including hidden csrf input in the form and also tried appending it to the url but same error
<form method="post" th:action="${'/add/' + id + '/documents?' + _csrf.headerName + '=' + _csrf.token}" enctype="multipart/form-data">
<input type="file" name="documents" multiple="multiple">
<input type="hidden"
th:name="${_csrf.headerName}"
th:value="${_csrf.token}" />
<input type="hidden" name="_csrf" th:value="${_csrf.token}">
<button class="btn btn-success btn-l">Upload</button>
</form>
Have a controller advice like this for csrf injection
@ControllerAdvice
public class SecurityAdvice {@ModelAttribute("_csrf")Mono<CsrfToken> csrfToken(final ServerWebExchange exchange) {
final Mono<CsrfToken> csrfToken = exchange.getAttributeOrDefault(org.springframework.security.web.server.csrf.CsrfToken.class.getName(), Mono.empty());
return csrfToken;
}
In security I have the following bean:
@Bean
public ServerCsrfTokenRepository csrfTokenRepository() {
WebSessionServerCsrfTokenRepository repository =
new WebSessionServerCsrfTokenRepository();
repository.setHeaderName("X-CSRF-TK");
return repository;
}
and using it like this in my SecurityWebFilterChain:
.and().csrf().csrfTokenRepository(csrfTokenRepository())
UPDATE:
Disabling csrf for a few urls would be enough too. Found a few examples but all of them are for Servlet based version. https://sdqali.in/blog/2016/07/20/csrf-protection-with-spring-security-and-angular-js/