Spring-Security 파일업로드 & Ajax Post 요청 방법

유재훈·2023년 5월 9일
0

Spring_Study

목록 보기
4/9

Spring Project를 진행하며 회원가입 시 프로필 사진 추가를 위해 첨부파일을 추가하였다.

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 

<form:form name="empFrm"
      action="${pageContext.request.contextPath}/emp/empEnroll.do" 
      method="post"
      enctype="multipart/form-data">
      
      	<table id="emp-enroll-table"></table>
        
</form:form>

하지만 오류가 발생하였다.

request method 'post' not supported

원인은 CSRF Token이 없어서였다.

CSRF Token 개념

CSRF (Cross-Site Request Forgery) Token은 웹 보안에 사용되는 기술로, 웹 어플리케이션에서 발생하는 CSRF 공격을 방지하는 데 사용된다.

CSRF 공격은 웹 어플리케이션 사용자가 악의적인 웹사이트에 방문할 때 발생할 수 있다. 공격자는 악의적인 웹사이트를 통해 사용자의 브라우저에서 해당 웹 어플리케이션에 요청을 보내고, 사용자는 이를 모르고 실행합니다. 이렇게 함으로써 공격자는 사용자의 계정으로부터 해당 웹 어플리케이션에 대한 액세스를 획득하거나 데이터를 조작할 수 있다.

CSRF Token은 이러한 공격을 방지하기 위해 사용자의 세션과 연관된 무작위의 문자열이다. 웹 어플리케이션은 사용자의 모든 요청에CSRF Token을 포함시키고, 이 Token이 제대로된지 확인한다. 공격자는 CSRF Token을 알지 못하므로, 이 Token이 유효하지 않으면 해당 요청은 거부된다.

따라서, CSRF Token은 웹 어플리케이션에서 발생할 수 있는 CSRF 공격으로부터 보호하는 데 중요한 역할을 한다.

Spring Security CSRF Filter

Spring Security는 모든 양식에 CSRF Token을 자동으로 추가함으로써 CSRF 공격으로부터 애플리케이션을 보호하는 쉽고 효과적인 방법을 제공한다. 애플리케이션에서 Spring Security를 구성하면 기본적으로 CSRF 필터가 필터 체인에 추가된다. 이 필터는 고유한 CSRF Token을 생성하고 애플리케이션의 모든 양식에 숨겨진 입력 필드로 추가한다. 양식이 제출되면 CSRF Token이 요청 본문에 포함되고 서버에서 확인하여 요청이 악의적인 소스가 아니라 동일한 애플리케이션에서 시작되었는지를 확인할 수 있다. 그러면 왜 multipart/form-data와 Ajax 요청 시 CSRF Token을 따로 추가해야 할까?

multipart/form-data와 Ajax 요청 시 CSRF Token을 따로 추가해야되는 이유

multipart/form-data와 Ajax 요청은 구조화 및 데이터 전송 방식에 표준 양식 요청과 다르다.

표준 양식 요청에서 양식 데이터는 일반적으로 요청 본문으로 전송된다. CSRF 토큰은 양식이 제출될 때 요청 본문에 자동으로 숨겨진 입력 필드에 포함된다.

multipart/form-data 요청에서 양식 데이터는 파일 데이터 및 기타 양식 필드를 포함하여 별도의 부분으로, Ajax 요청에서 양식 데이터는 일반적으로 요청 본문의 JSON 데이터로 전송된다. CSRF 토큰은 요청 본문에 자동으로 포함되지 않으므로 요청 헤더에 별도로 추가하거나 양식 데이터(양식 필드로 별도로 추가(multipart/form-data) / JSON 데이터에 포함(Ajax))에 별도로 추가해야 한다.

요약하면 모든 유형의 요청에는 CSRF 공격으로부터 보호하기 위한 CSRF Token이 포함되어야 하는데 포함되는 방식은 요청 유형에 따라 다를 수 있다. Spring Security는 표준 양식 요청에 대해 이를 자동으로 처리하는 매커니즘을 제공하지만, Ajax 및 multipart/form-data 요청의 경우 CSRF 토큰을 요청 헤더 또는 양식 데이터에 별도로 추가해야 한다.

Spring-Security 첨부파일 방법

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 

<form:form name="empFrm"
      action="${pageContext.request.contextPath}/emp/empEnroll.do?${_csrf.parameterName}=${_csrf.token}" 
      method="post"
      enctype="multipart/form-data">
      
      	<table id="emp-enroll-table"></table>
        
</form:form>

url 뒤에 ?${_csrf.parameterName}=${_csrf.token}을 추가해주면 된다.

Spring-Security Ajax Post 요청 방법

const csrfHeader = "${_csrf.headerName}";
const csrfToken = "${_csrf.token}";
const headers = {};
headers[csrfHeader] = csrfToken;
	
	$.ajax({
	   url : '${pageContext.request.contextPath}/workingManagement/insertStartWork.do',
	   method : 'POST',
	   headers,
	   contentType : "application/json; charset=utf-8",
	   success(data){
			console.log(data);
	   },
	   error : console.log
   });

headersajax요청에 같이 보낸다.

0개의 댓글