금백조의 개발 블로그

[Spring]CSRF 토큰이 Multipart 이미지 전송에서 인식되지 않는 이슈 해결 방법(Error Message : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.) 본문

Web/Spring

[Spring]CSRF 토큰이 Multipart 이미지 전송에서 인식되지 않는 이슈 해결 방법(Error Message : Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.)

금백조 2021. 12. 18. 17:17
반응형

서론

 

Spring 프로젝트를 진행하던 중 이미지 전송을 위해 enctype="multipart/form-data"인 form 태그 안에 아래와 같이 CSRF 토큰을 기술해도 Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.이라는 에러 메시지가 나타나며 인식하지 못하는 에러가 발생했습니다. 이번 포스팅에서는 이에 대한 해결 방법을 다뤄보려 합니다.

 

<form action="/url" method="post" enctype="multipart/form-data">
	<input type="hidden" name="${_csrf.parameterName }" value="${_csrf.token }" />
</form>

 

 

본론

 

multipart/form-data 전송에서 CSRF 토큰을 사용하기 위해선 Spring Framework에 구현된 MultipartFilter 기능을 활성화해야 합니다.

 

[테스트 환경]

 

Spring 4.3.12

Apache Commons FileUpload 라이브러리 사용

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload

 

[해결 방법]

 

1. tomcat의 context.xml에 기술된 Context 태그 안에 allowCasualMultipartParsing 속성을 true로 설정

 

[context.xml]

<Context allowCasualMultipartParsing="true" path="/">
    <Resources cachingAllowed="true" cacheMaxSize="100000" />
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

 

2. web.xml에 아래 예제처럼 springSecurityFilterChain보다 반드시! 앞에 MultipartFilter 추가 (앞에 추가하지 않으면 동일하게 CSRF토큰 인식 불가능 에러가 발생함.)

 

[web.xml]

  <filter>
     <display-name>springMultipartFilter</display-name>
     <filter-name>springMultipartFilter</filter-name>
     <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
  </filter>
  <filter-mapping>
     <filter-name>springMultipartFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping> 
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

 

위의 설정들을 해주고 나면 CSRF 토큰이 Mutipart 전송에서도 제대로 인식하게 됩니다.

 

결론

 

CSRF 토큰을 Mutipart 전송에서 사용하기 위해선 MultipartFilter가 필요한 걸 알게 된 좋은 경험이었습니다. 구현된 자세한 소스는 아래 링크에서 확인하실 수 있습니다.

 

https://github.com/GoldSwan/PictureRepository

 

GitHub - GoldSwan/PictureRepository: Web Side Project with Spring

Web Side Project with Spring. Contribute to GoldSwan/PictureRepository development by creating an account on GitHub.

github.com

 

반응형