CSRF
Spring Security에서는 기본적으로 POST 요청에 대해서 거부하도록 설정되어 있다. CSRF 공격으로 부터 예방하기 위해서 인데 POST 요청을 혀용하는 방법으로 GET 요청시 반환되는 토큰을 헤더에 넣어 보내면 POST 요청을 허용하는 방식이다. (기본적으로 데이터가 변경되기 전에 데이터를 조회 또는 view를 렌더링해야한다는 조건이 포함되는 것이다)
public class CsrfTokenLogger implements Filter {
private Logger logger= Logger.getLogger(CsrfToken.class.getName());
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Object o=request.getAttribute("_csrf");
CsrfToken token= (CsrfToken) o;
logger.info("CSRF token "+token.getToken());
chain.doFilter(request,response);
}
}
CsrfTokenLogger 에 필터기능을 구현하여 토큰을 로깅하도록 설정하였다.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
//중략
.addFilterAfter(
new CsrfTokenLogger(), CsrfFilter.class
)
//중략
}
필터 체인에 CsrfTokenLogger를 필터를 뒤에 추가시켜 모든 인증, 인가 조건을 충족하였을때 토큰을 반환하도록 하였다.(현재는 로깅만 되는 상태이므로 실제로는 response에 담아져야 한다.)
또한 서버가 토큰값을 저장하므로 세션ID를 알야한다.
토큰값과 세션ID를 모두 request에 넣어보내야 POST 통신이 성공하게 된다.
CORS
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().permitAll()
);
return http.build();
모든 요청을 허락하는 filterChain을 구현하였다.
그러나 cors정책에 의해 다른 주소로의 요청이 막히는 것을 확인할 수 있다.
스프링에서 cors 정책에 대한 해결법으로 두가지를 제시하고 있는데
- @CrossOrigin(허용주소)
- CorsConfigurationSource을 통한 cors 허용
나는 2번의 방법을 사용했다.
https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:8080"));
configuration.setAllowedMethods(Arrays.asList("GET","POST", "PUT", "DELETE", "OPTIONS"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.anyRequest().permitAll()
)
//.cors(AbstractHttpConfigurer::disable)
.cors(corsConfigurer -> corsConfigurer.configurationSource(corsConfigurationSource()))
.csrf(AbstractHttpConfigurer::disable);
return http.build();
}
cors diable 시도는 무슨 이유인지 확인되지 않았지만 실패하였다
여담으로 400에러가 계속 발생하여 cors을 확인하지도 못했었는데 이전에 구현한 filter가 자동으로 의존주입이 되어 있는 것이 확인되었다..
'보안' 카테고리의 다른 글
[Spring Security in action] OAuth 2 실습해보기 (0) | 2024.02.04 |
---|---|
[Spring Security in action] 인증 필터 (0) | 2024.01.20 |
[Spring Security in action] 권한부여 (0) | 2024.01.20 |
[Spring Security in action] SecurityContext (0) | 2024.01.18 |
[Spring Security in action] AuthenticationProvider을 사용한 인증 (0) | 2024.01.16 |