본문 바로가기

웹프로그래밍/spring~~

Spring security CSRF 프로텍션

Spring security를 이용해서 로그인을 구현하고 나니 

<form id="frm" name="frm" method="post" action="#" th:action="@{/jpa/board/write}" enctype="multipart/form-data">

 

위의 form 태그에 대해서 submit을 하니까 아래의 페이지가 떴다 처음에는 mapping 관련 문제인 줄 알고 고민하고 진짜 여러가지 시도를 하다가 혹시나 하는 마음에 Spring security 관련 부분을 모두 주석 처리하니까 다시 잘된다....

 

이유는 multipart/form-data로 전송시 csrf프로텍션이 적용되서 그렇다고 한다.

CSRF(Cross Request Forgery: 사이트 간 요청 위조)인데 보안 대책으로 필수적으로 요구 된다고 한다. 

csrf-multipart 관련 Spring Security Reference

https://docs.spring.io/spring-security/site/docs/4.2.2.RELEASE/reference/htmlsingle/#csrf-multipart

해결 책을 보면 web.xml에 multipartfilter를 사용하라고 하는데 spring-boot로 개발중이여서 web.xml이 없다. 

 

그래서 차선책으로 제시된 url에 csrf 토큰을 보내는 방법을 사용했다.

 

우선 gradle에 기존의 spring-boot-security는 지우고

spring-security-config와 spring-security-web을 추가한다

 

implementation group: 'org.springframework.security', name: 'spring-security-config', version: '5.1.5.RELEASE'
implementation group: 'org.springframework.security', name: 'spring-security-web', version: '5.1.5.RELEASE'
//implementation 'org.springframework.boot:spring-boot-starter-security'

그리고 form 태그의 url을 th:action 으로 바꾸고 뒤에 토큰 값을 붙인다

<form id="frm" name="frm" method="post"
		  th:action="@{/jpa/board/write(${_csrf.parameterName}=${_csrf.token})}" enctype="multipart/form-data">

 

그 이외에 만약 post방식 이지만 multipart/form-data가 아니라면 <form> 태그 사이에 아래의 내용을 넣어 전송시 csrf 토큰을 같이 전송 시켜주면 오류가 해결된다.

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
반응형