본문 바로가기

Language & Framework/삽질기록

삽질기록 (7) 스프링 시큐리티(JWT)적용 이후 깨지는 테스트들 복구하기..

 

초기에 내 생각과 달리 시큐리티를 이용한 JWT, OAut2 구현에 거의 열흘에 가까운 시간을 투자해버렸고, 그로 인해 구현만 할 줄 알고 테스트는 어떻게 처리해야할지 몰랐던 나는 @WithMockUser로 테스트가 진행이 안되길래.. 나를 제외한 팀원 분들은 시큐리티에 대해 거의 아무것도 모르는 상황이라, 일단 Security를 아예 끄고 진행하자!라는 무식한 방법을 택했고, 시큐리티를 모두 구현한 이후에도 며칠간 차일피일 미뤘다.

변명이 아니고 정말 리액트까지 하느라 일주일에 두 번씩 밤을 새워도 시간이 모자라서 어쩔 수 없었다 ㅎ..

 

그리고 서버에 올리기 위해 이제는 정말 시큐리티를 켤 수 밖에 없었다.

그렇게 펼쳐진 대환장 파티.

 

 

 

ㅋㅋ 아.. 이건 좀..

일단 첫 번째로 저렇게 빨간불이 나오던 이유는 OAuth2 때문이였다.

라고 생각하고 내가 해결책을 찾아서 해결했었는데, 문제는 현재 해당 설정을 해제했음에도 테스트가 잘 진행된다..

그래서 지금 시점에서는 첫 번째 문제는 원인을 알 수 없게 되어버렸다.

잘못된 정보 전달은 피하고 싶으므로 이건 패스하겠다..

 

이제 두 번째.

 

 

 

위에 이미지가 너무 길어서 이번에는 짧게 올렸다.

거의 대부분의 컨트롤러 테스트에서 403 Forbidden 에러가 터져나왔다.

지금 생각해보면 너무나도 명확한 힌트가 바로 위에 있었다..

 

후..

하지만 나는 오직 CostumFilter, CostumProvider, CostumToken으로 jwt를 구현해서 @WithMockUser가 안 먹히는 것으로만 생각했다.

구글에 관련 검색을 해봤을때도 이것 때문에 어려움을 겪는 사람들이 많았고, 결국 또 나의 확증편향이 미쳐날뛰고 말았다.

 

이로 인해 버린 시간이 무려 이틀이다.

 

스프링 공식 문서와 스택오버플로우의 수많은 글에 나오는 모든 방법을 다 시도해봤으나 도저히 어떤 방법으로도 상황이 나아질 기미를 보이지 않았고, 디버깅을 해봐도 잡히는 건 아무것도 없었다.

 

밀려오는 자괴감 속에서 머리를 감싸고 화면을 보는데..

 

getProfile의 초록색 체크표시가 갑자기 눈에 들어왔다.

우리 프로젝트에서 getProfile은 ROLE_USER 이상만 접근할 수 있다.

 

 

??

 

인가가 똑바로 되고 있다.

근데 403이다.

 

나는 ide에서 지원하는 디버깅에만 집착하고 있었는데, 테스트시 디버깅 로그를 볼 수 있다는 게 불현듯 떠올랐다.

 

 

 

바로 시큐리티 로그를 볼 수 있게 application.yml 설정을 변경했다.

그리고 내가 찾아낸 문제는 바로..

 

 

 

 

Invalid CSRF token found for http://localhost:8080/posts/1/comments/1

..??

???

 

아니 왜..

왜 인가 제한 정보는 받으면서 csrf().disable() 정보는 안 받는 건데..????????????

 

https://www.baeldung.com/spring-security-integration-tests

 

Spring Security for Spring Boot Integration Tests | Baeldung

Learn how to execute Spring Security enabled integration tests

www.baeldung.com

 

Baeldung에도 WebMvcTest가 자동으로 Security Configuration을 등록한다고 되어 있는데.. 

 

소스코드에도 그렇게 적혀있는데.. 대체 뭐지?? 내가 뭘 모르고 있는 건지 혼란스럽다..

csrf는 Original Filter에 해당하는 부분이라 내가 Security FilterChain에 등록한 게 반영되지 않는 건가..?

공식 문서에도 마땅히 이렇다할 설명을 찾지 못해서 명확한 원인은 알 수 없게 되었다.

 

정말 허탈하다..

이걸 해결할 수 있는 방법은 다음과 같다.

 

 

1. 일일히 csrf토큰 쥐어주기.

 

        ResultActions actions = mockMvc.perform(
                delete("/posts/{post-id}/comments/{comment-id}/{re-comment-id}",
                        postId, commentId, reCommentId).with(csrf())
        );

 

하지만 이런 반복 작업은 못 참는다..

 

 

2. TestConfiguration으로 FilterChain설정 등록하기

 

 

나 같은 경우 이렇게 한 번에 들고와서 해봤는데 의존성 문제가 생겼고, 아마 이것도 해결할 방법이 없지는 않겠지만 테스트에 중요하지 않은 것들은 그냥 빼버려도 되지 않을까 하는 생각이 들었다.

 

 

 

그래서 이렇게 모두 빼준 뒤에..

 

 

 

 

이렇게 붙여줬다.

 

결과는?

 

 

 

이제 권한이 부족하면 403, 충분하면 성공한다..

이렇게 별것도 아닌 걸로 이틀을 날렸다니 ^^..

 

이렇게 구질구질하게 하지 않아도 SecurityFilterChain을 테스트에 정상적으로 적용시킬 방법이 있을 법 한데.. 당장은 못 찾겠다.

일단 성공한 것만으로 감지덕지..