에러
AJAX 비동기 요청으로 GET 에서는 정상적으로 작동하던 메서드가, POST로만 바꾸면 응답을 302로 보내는 문제가 있었습니다.
아무리 이것 저것 다 체크를 해 보아도 응답이 /denied
로 가는 리다이렉트가 됩니다. 그래서 결국 denied(text) 라는 텍스트만 덜렁 뜨는 상황이 발생했습니다. 로그인을 한 상태임에도 스프링 시큐리티가 권한을 체크 하다가 뭔가 잘못되었나 싶어서 .permitAll()
로 변경을 해 보아도 마찬가지였습니다.
원인
스프링 시큐리티의 CSRF(Cross-Site Request Forgery) 설정 때문 입니다.
스프링 시큐리티에서는 csrf 설정이 기본적으로 enabled 되어 있기 때문에 csrf 에 대한 토큰을 받도록 명시되어 있으며 GET 요청이 아닌 요청, 그러니깐 POST/PUT/DELETE/PATCH
는 CSRF 토큰이 포함 되어 있어야만 서버에 요청이 가능합니다.
해결
필요한 요청에 CSRF 토큰을 담거나, 혹은 Spring Security의 기본 csrf 설정을 disable 시키는 방법이 있습니다.
회사에서 봤던 대부분의 코드들도 csrf가 disable 되어있던 기억이 있는데요, CSRF 설정에 대해 알아보고 disabled 해도 될지 먼저 알아봅니다.
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html
일반적인 유저로부터 일반적인 브라우저 요청을 받을 때에는 CSRF 방어가 추천된다고 합니다. 다만, non-browser client 를 통한 서비스를 만들 경우에는 disable 시키는게 필요 할 거라고 합니다.
CSRF 방어가 꼭 필요한 경우에 대해서도 명시가 되어 있는데요. 예를 들어 JSESSIONID 대신에 모든 정보를 한번에 담고 있는 쿠키를 인증용도로 사용하고 있는 경우 커스텀 쿠키를 통해 CSRF 공격이 발생 하면 요청과 함께 해당 커스텀 쿠키가 보내지고, 유저이름과 비밀번호등의 인증 정보가 탈취 될 수 있을 거라고 합니다. 사실 요즘에는 단순 쿠키로 인증을 하는 경우는 거의 없고 SameSite 쿠키 속성도 까다로워 졌죠.
위의 csrf 링크를 참고해서 disable 시켜도 될지에 대해 고민 후 괜찮겠다 싶으면 비활성화를 시킵니다.
비활성화
스프링 시큐리티 공식 문서에 따르면 아래와 같은 방법으로 csrf를 disable 할 수 있도록 안내하고 있습니다.
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html
테스트
csrf().disabled()
이후 다시 확인 해보면..
이제 정상적으로 응답을 받아옵니다.
이상입니다.
References
'Development > Daily Error' 카테고리의 다른 글
[Java Mail] Could not convert socket to TLS; 문제 해결 (0) | 2022.10.12 |
---|---|
[POI] 엑셀의 숫자를 소수점으로 파싱하는 문제 해결하기 (0) | 2022.08.25 |
[Spring Redis] incompatible types for field 해결 (0) | 2022.08.17 |
[Java] Unsupported class file major version 61 해결하기 (0) | 2022.08.14 |
[JPA] No Dialect mapping for JDBC type: 1111 (0) | 2022.06.28 |