[Spring] Spring-Security Test를 위한 @WithMockUser 커스터마이징

윤성철·2024년 8월 27일

Back-End

목록 보기
12/22
post-thumbnail

서론

Spring Security + OAuth 2.0 + JWT로 인증·인가를 구현한 프로젝트에서 컨트롤러 단위 테스트 코드를 작성중 발생한 문제 상황이다. Controller에 도착하기 전 Filter가 가로채서... /login 경로로 리다이렉트시켜 인증을 요구한다.

Mock 객체를 SecurityContextHolder에 담는 방법을 탐색하다가 해당 방법론을 적용하게 되었다.

본론

@WithMockUser

Spring Security를 적용한 프로젝트에서 가장 일반적으로 사용되는 어노테이션이다.

  • username, password, roles를 Mock에 바인딩해 사용한다.
  • authentication말고도 principal에도 유저 정보를 바인딩해주고, SpringContext에도 올라간다.

그러나 위 방법은 직접 만든 Authentication 인증정보에는 사용이 불가능하다.

인증, 인가를 구현하면서 CustomOAuthUser 객체에 사용자 정보를 담고 SecurityContextHolder에 담도록 개발했기 때문에, 위 어노테이션은 사용이 불가능하다..

@WithUserDetails

위 어노테이션과 차이점은 UserDetails 객체를 조회해서 인증 정보를 만든다는 점이다.
마찬가지로, CustomOAuthUser 객체를 통해 Authentication을 생성하지 않기 때문에, 이 방법도 적용이 불가능했다.

해결 방법

@WithSecurityContext

  • Authentication을 커스텀한 경우에 사용하는 방법이다.

순서

  1. @WithSecurityContext 어노테이션이 적용된 커스텀 어노테이션을 작성한다.
    • SecurityContextFactory를 빈으로 주입받아서 SecurityContext를 만든다.
  2. SecurityContextFactory를 구현한다.

커스텀 어노테이션 작성 @WithMockCustomUser

SecurityContextFactory 클래스 생성

OAuth2 인증정보로 사용자 객체를 생성할 때, UserDto -> CustomOAuth2User 객체를 만들어 Authentication을 생성한다.
생성한 Authentication을 SecurityContext에 담는다.

테스트 실행

  • 사용자 정보 조회 Controller 테스트 코드

  • 실행 결과

위 @WithMockUser와의 차이점은 내가 커스텀한 Authentication == CustomOAuth2User 객체가 바인딩되어서 정상적으로 filter를 통과하고 controller에 대한 테스트가 정상 수행됐다는 점이다.

profile
내 기억보단 내가 작성한 기록을 보자..

0개의 댓글