일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- jpa n+1 문제
- 자료구조
- 점근적 표기법
- 완전이진트리
- JVM
- 백준 장학금
- 엔티티 그래프
- 힙트리
- 연결리스트 종류
- MSA
- 프로세스
- 백준장학금
- AVL트리
- spring
- python
- 스케줄링
- JPA
- heapq
- 알고리즘
- Kruskal
- 강화학습
- 이분탐색이란
- HTTP
- posix
- SpringSecurity
- 최대 힙
- 최소힙
- 연결리스트
- 멀티프로세서
- 운영체제
- Today
- Total
KKanging
[SpringSecurity] Cors 와 CorsFilter 뜯어보기 본문
CorsFilter
CorsFilter는 서버의 Cors 공격을 막기 위한 Fitler이다. 같은 Origin 이 아닌 출처에 대한 요청을 막기위함이다.
Cross-Origin이란?
위와 같이 프로토콜 + hostname + port 중에 하나라도 다르면 Cross Origin 모두 같으면 동일한 Origin이라고 칭한다.
옛날에는 서버 와 프론트 서버가 동일한 서버에 있는 경우가 많았으므로 위와 동일한 Origin 에 대한 요청만 허용하도록 해서 보안을 강화하였다.
하지만 요즘에는 API 서버로 많이 사용하기 때문에 프론트 서버와 백엔드 서버가 다른 경우가 많다. 이런 경우에는 대부분 백엔드 서버에서 특정 Origin을 명시적으로 허용해줘야 한다.
즉
Origin : protocal + hostname + port
same Origin : Origin이 완전히 똑같은
백엔드 개발자가 해야하는 일
프론트 서버의 Origin은 Cross Origin이라고 하더라도 허용하는 설정을 해줘야함
CorsFilter 뜯어보기
CorsFilter는 GenericFilter 를 상속 받았다. 그런데 Security의 다른 Filter들은 GenericFitlerBean이나 OncePerRequestFilter 를 상속 받았다
- 사실 OncePerRequestFilter도 GenericFitlerBean을 상속 받았기 때문에 무슨 차이일까
GenericFilter와 GenericFilterBean의 차이
GenericFilter는 스프링과의 상관없는 추상 클래스이다.
하지만 GenericFitlerBean은 스프링이 제공하는 추상 클래스이다. 그리고 스프링에서 제공하므로 당연히 스프링의 Bean 컨테이너 또한 사용이 가능하다.
위처럼 스프링의 의존적이어서 스프링 관련 기능을 사용할 수 있냐 없냐의 차이점이 있다.
@Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
final FilterChain filterChain) throws IOException, ServletException {
if (!(servletRequest instanceof HttpServletRequest) || !(servletResponse instanceof HttpServletResponse)) {
throw new ServletException(sm.getString("corsFilter.onlyHttp"));
}
// Safe to downcast at this point.
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// Cors 인지 체크
CorsFilter.CORSRequestType requestType = checkRequestType(request);
// Cors 체크의 결과에 따라 request 에 값 저장
if (isDecorateRequest()) {
decorateCORSProperties(request, requestType);
}
// Cors 체크의 결과에 따라 처리를 구현함
switch (requestType) {
case SIMPLE:
// Handles a Simple CORS request.
case ACTUAL:
// Handles an Actual CORS request.
this.handleSimpleCORS(request, response, filterChain);
break;
case PRE_FLIGHT:
// Handles a Pre-flight CORS request.
this.handlePreflightCORS(request, response, filterChain);
break;
case NOT_CORS:
// Cors 통과
this.handleNonCORS(request, response, filterChain);
break;
default:
// Handles a CORS request that violates specification.
this.handleInvalidCORS(request, response, filterChain);
break;
}
Cors 설정 구현하기
위와 같이 allowedOrigin이 CorsConfigurationSource 설정으로 부터 가지고 온다.
CorsFilter는 Security에서 제공하는 Filter가 아니지만 내장이 되어있어서 Security에 FilterChain 설정 시에 해도 되고 따로 Bean 등록으로 설정해도 된다.
Bean 등록으로 설정하기
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("<https://example.com>"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
<http>
<cors configuration-source-ref="corsSource"/>
...
</http>
<b:bean id="corsSource" class="org.springframework.web.cors.UrlBasedCorsConfigurationSource">
...
</b:bean>
Security에서 설정하기
- 비활
http
.cors((cors)->cors.disable());
2. 디폴트
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
// if Spring MVC is on classpath and no CorsConfigurationSource is provided,
// Spring Security will use CORS configuration provided to Spring MVC
.cors(withDefaults()) // 혹은 설정 안하기
...
return http.build();
}
}
3. 특정 Origin 허용
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.cors((cors) -> cors
.configurationSource(apiConfigurationSource()));
return http.build();
}
CorsConfigurationSource apiConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("<https://api.example.com>"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
참고 문헌
'백엔드 > SpringSecurity' 카테고리의 다른 글
[SpringSecurity] 인증 과정 뜯어보기 (0) | 2024.05.26 |
---|---|
[SpringSecurity] SecurityContextFilter 코드 뜯어보기 (0) | 2024.05.23 |
[SpringSecurity] security filter 커스텀 기초 와GenericFilterBean,OncePerRequestFilter (0) | 2024.05.22 |
[SpringSecurity] SecurityContextHolder ,Security Context, Authentication (0) | 2024.05.19 |
[SpringSecurity] Security 전체적인 아키텍처 (0) | 2024.05.17 |