[Spring Security] 스프링 시큐리티 403 Forbidden 에러
개요
토이프로젝트를 진행하던 도중에 스프링 시큐리티를 설정하고 나서, 로그인 인증을 마쳤는데도 403 Forbidden 에러가 계속해서 발생하였습니다. 에러가 발생하는 시점이 GET 요청은 무리없이 잘 되는데, POST 요청으로 보내면 이상하게 403 에러가 나는데 이유를 모르겠습니다.
SecurityConfig를 살펴보자
아래는 기존 시큐리티 설정 코드입니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").authenticated()
.antMatchers("/user/**").permitAll()
.and()
.formLogin()
.disable()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.defaultSuccessUrl("/");
}
혹시 몰라서 "/user/**"요청을 permitAll() 시켜줬는데도 계속 403 에러가 발생했습니다.
알고 보니까 문제는 http.csrf().disable(); 를 설정해주지 않아서
스프링 시큐리티를 추가하면 기본적으로 csrf에 대해 체크하기 때문에 프론트에서 CSRF 토큰을 처리해주지 않았기 때문에 POST가 정상적으로 수행되지 않았던 것입니다.
아래처럼 http.csrf() 를 disable() 해주도록 합시다!
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").authenticated()
.antMatchers("/user/**").permitAll()
.and()
.formLogin()
.disable()
.and()
.logout()
.logoutSuccessUrl("/")
.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService)
.and()
.defaultSuccessUrl("/");
}
왜 이런 현상이 발생했을까?
그 전에 먼저 CSRF에 대해서 알아야 합니다. CSRF(Cross Site Request Forgery)란 사이트 간 요청 위조 즉, 사용자가 자신의 의지와 상관없이 공격자가 의도한 행위(수정, 삭제, 생성)를 특정 사이트로 요청하도록 하는 공격입니다.
(자세한 개념과 해결방법에 대해서는 추후에 포스팅 하겠습니다)
스프링 시큐리티에서는 csrf 토큰을 이용해서 방어를 하고 있습니다. 매 요청마다 csrf 토큰은 서버에서 임의의 난수를 생성하여 클라이언트에게 넘겨주는 것입니다. 그럼 이제 클라이언트는 서버로 요청할 때 발급받은 csrf 토큰과 함께 요청을 하면 서버에서는 csrf 토큰을 비교하여 위조된 요청인지 판별하게 되는 것입니다.
CSRF를 끄면 보안에 취약하지 않을까
만약 JWT와 같이 토큰 인증 방식을 사용한다면, 서버에 상태가 저장되지 않기 때문에 CSRF에 대해 보호가 필요하지 않습니다. 하지만 세션 쿠키 방식의 인증방식을 사용한다면 꼭 CSRF를 대비해야 합니다. 브라우저에 저장된 쿠키가 CSRF 공격의 매개체가 되기 때문입니다.
감사합니다.
참고
Cross Site Request Forgery (CSRF) :: Spring Security
When should you use CSRF protection? Our recommendation is to use CSRF protection for any request that could be processed by a browser by normal users. If you are creating a service that is used only by non-browser clients, you likely want to disable CSRF
docs.spring.io
Cross Site Request Forgery (CSRF) | OWASP Foundation
Cross Site Request Forgery (CSRF) on the main website for The OWASP Foundation. OWASP is a nonprofit foundation that works to improve the security of software.
owasp.org