[SPRING] Spring 보안 3.2 다중 요청에 대한 CSRF 지원
SPRINGSpring 보안 3.2 다중 요청에 대한 CSRF 지원
우리는 몇 년 동안 애플리케이션과 함께 Spring Security를 사용 해왔다. 지난 주 Spring Security를 버전 3.1.4에서 3.2.0으로 업그레이드했습니다. 업그레이드가 정상적으로 진행되었으며 업그레이드를 게시하는 동안 오류를 발견하지 못했습니다.
Spring Security 3.2.0 문서를 살펴보면서 CSRF 보호 및 보안 헤더에 대해 새로 추가 된 기능에 대해 살펴 보았습니다. 우리는 보호 자원에 대한 CSRF 보호를 가능하게하기 위해 Spring Security 3.2.0 문서의 지침을 따랐습니다. 일반 양식에서는 정상적으로 작동하지만 응용 프로그램에서는 여러 부분 양식에서는 작동하지 않습니다. 폼 제출시 CsrfFilter는 요청에 CSRF 토큰이 없으면 (DEBUG 로그를 통해 결정됨) 액세스 거부 오류를 발생시킵니다. 우리는 CSRF 보호를 다중 파트 폼과 함께 사용하기 위해 Spring Security 문서에서 제안 된 첫 번째 옵션을 사용해 보았습니다. URL을 통해 CSRF 토큰을 유출하고 보안 위험을 초래하므로 두 번째 제안 된 옵션을 사용하고 싶지 않습니다.
문서에 기반한 우리 구성의 관련 부분은 Github의 Gist로 사용할 수 있습니다. 우리는 Spring 버전 4.0.0을 사용하고 있습니다.
성공하지 못하면 다음 변형을 이미 시도했습니다.
업데이트 : 문서화 된 동작이 단일 페이지 샘플 앱에서도 작동하지 않음을 확인했습니다. 누구나 문서화 된 동작이 예상대로 작동하는지 확인할 수 있습니까? 사용할 수있는 예제 작업 응용 프로그램이 있습니까?
해결법
-
==============================
1.Spring Security 팀의 도움으로이를 해결할 수있었습니다. 작업 구성을 반영하도록 Gist를 업데이트했습니다. 나는 모든 것이 예상대로 작동하도록하기 위해 아래의 단계를 따라야 만했다.
Spring Security 팀의 도움으로이를 해결할 수있었습니다. 작업 구성을 반영하도록 Gist를 업데이트했습니다. 나는 모든 것이 예상대로 작동하도록하기 위해 아래의 단계를 따라야 만했다.
1. 공통 단계
@ holmis83의 대답에 설명 된대로 web.xml에 MultipartFilter를 추가하여 Spring Security 구성 전에 추가되도록합니다.
<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> <display-name>springSecurityFilterChain</display-name> <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> <dispatcher>ERROR</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping>
2.1. Apache Commons Multipart Resolver 사용하기
루트 Spring 애플리케이션 컨텍스트에 filterMultipartResolver라는 Apache Commons Multipart Resolver 빈이 존재하는지 확인한다. 이 부분을 다시 강조하겠습니다. 다중 부분 해결자가 루트 Spring 컨텍스트 (일반적으로 applicationContext.xml)에 선언되어 있는지 확인하십시오. 예를 들어,
을 포함한다.
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:springWebMultipartContext.xml </param-value> </context-param>
springWebMultipartContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="100000000" /> </bean> </beans>
다른 bean 이름은 web.xml에 구성된 MultipartFilter에 의해 선택되지 않으므로 bean이 filterMultipartResolver로 호출되는지 확인하십시오. 이 bean의 이름이 multipartResolver이므로 초기 구성이 작동하지 않습니다. 나는 심지어 web.xml init-param을 사용하여 MultipartFilter에 빈 이름을 전달하려고 시도했으나 작동하지 않았다.
2.2. Tomcat Multipart 지원 사용
Tomcat 7.0+에는 멀티 파트 지원 기능이 내장되어 있지만 명시 적으로 활성화해야합니다. 전역 Tomcat context.xml 파일을 다음과 같이 변경하거나 WAR 파일에 로컬 context.xml 파일을 포함하여이 지원이 응용 프로그램을 변경하지 않고 작동하도록하십시오.
<Context allowCasualMultipartParsing="true"> ... </Context>
아파치 커먼즈 멀티 파트 리졸버 (Apache Commons Multipart Resolver)를 사용하여 이러한 변경 작업을 한 후에는 Tomcat, Jetty 및 Weblogic에서 지금까지 애플리케이션이 작동하고 있습니다.
-
==============================
2.이 부분:
이 부분:
<filter-mapping> <filter-name>multipartFilter</filter-name> <servlet-name>/*</servlet-name> </filter-mapping>
해야한다:
<filter-mapping> <filter-name>multipartFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Spring Security 3.2.0 문서의 오류입니다. 버그가보고되었으며 곧 출시 될 버전에서 수정 될 것입니다.
-
==============================
3.이 문제로 조금 어려움을 겪은 후, 멀티 파트 컨텐트의 일부로 포함 된 CSRF 토큰을 얻으려고 시도하는 대신 스프링 보안에 정의 된 요청 헤더를 사용하여 훨씬 쉬운 솔루션을 발견했습니다.
이 문제로 조금 어려움을 겪은 후, 멀티 파트 컨텐트의 일부로 포함 된 CSRF 토큰을 얻으려고 시도하는 대신 스프링 보안에 정의 된 요청 헤더를 사용하여 훨씬 쉬운 솔루션을 발견했습니다.
다음은 jsp에서 파일 업로드를 위해 AJAX 라이브러리를 사용하여 헤더를 설정하는 간단한 방법입니다.
var uploader = new AjaxUpload({ url: '/file/upload', name: 'uploadfile', multipart: true, customHeaders: { '${_csrf.headerName}': '${_csrf.token}' }, ... onComplete: function(filename, response) { ... }, onError: function( filename, type, status, response ) { ... } });
어느 쪽이 헤더와 함께 멀티 파트 요청을 보냈는지 :
X-CSRF-TOKEN: abcdef01-2345-6789-abcd-ef0123456789
헤더의 태그에 포함시키기위한 권장 사항은 제출시 요청을 중단하고 javascript를 통해 헤더를 추가 한 다음 제출을 완료하면 정상적으로 작동합니다.
<html> <head> <meta name="_csrf" content="${_csrf.token}"/> <!-- default header name is X-CSRF-TOKEN --> <meta name="_csrf_header" content="${_csrf.headerName}"/> <!-- ... --> </head> <body> <!-- ... --> <script> var token = $("meta[name='_csrf']").attr("content"); var header = $("meta[name='_csrf_header']").attr("content"); // Do whatever with values </script> </body> </html>
추가 정보 : Spring Security - AJAX 및 JSON 요청에 대한 CSRF
-
==============================
4.대부분의 답변은 서버 년 전에 답변을 찾으십시오.
대부분의 답변은 서버 년 전에 답변을 찾으십시오.
필요한 경우
이 블로그는 https://cloudnative.tips/passing-csrf-tokens-with-resttemplate-736b336a6cf6을 매우 계몽하고 있습니다.
Spring Security 5.0.7.RELEASE에서
https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-multipart
즉, 첫 번째 옵션은 더 안전하며 후자는 더 쉽습니다.
다른 옵션
from https://stackoverflow.com/questions/21397939/spring-security-3-2-csrf-support-for-multipart-requests by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 일치하는 와일드 카드는 엄격하지만 요소의 컨텍스트에 대한 선언을 찾을 수 없습니다. component-scan (0) | 2018.12.08 |
---|---|
[SPRING] 스프링 MVC 컨트롤러에 대한 GET 요청에서 날짜 매개 변수를 수락하는 방법? (0) | 2018.12.08 |
[SPRING] 모든 응답에 헤더를 자동으로 추가합니다. (0) | 2018.12.08 |
[SPRING] <mvc : annotation-driven />를 제거하는 방법? (0) | 2018.12.08 |
[SPRING] Spring Rest Template + Spring Web MVC를 이용한 다중 파일 업로드 (0) | 2018.12.08 |