본문 바로가기
Spring/Spring Security

[Spring Security] Spring Security 테스트하기

by yoon_seon 2023. 10. 29.

SpringSecurity를 사용하는 프로젝트에서의 테스트는 SpringSecurity가 없는 테스트와 다른 부분이 있다.

SpringSecurity의 테스트에서는 User가 로그인한 상태를 가정하고 테스트해야 하는 경우가 많은데 인증을 받지 않은 상태로 테스트를 하면 SpringSecurity에서 요청 자체를 막아버려서 테스트가 제대로 동작하지 못한다.

 

이런 문제를 해결하기 위해 spring-security-test를 사용하여 해결할 수 있다.

spring-security-test를 사용하면 테스트 직전 Mock User를 인증시켜놓고 테스트를 구동할 수 있다.

build.gradle에 의존성을 추가한다.

 

Test 실행 전 MockMvc에 springSecurity (static 메서드)를 설정한다.

 

 

@WithMockUser

Mock User를 생성하고 Authentication을 만듭니다. 여기서 User는 org.springframework.security.core.userdetails.User 이다.

위와 같이 사용하며 내부 속성은 다음과 같다.

맴버변수 예시 설명
roles USER 권한('ROLE_' 자동으로 붙음)
authorities ROLE_USER 권한(사용하면 roles를 무시함)
username user123 유저명
password password123 패스워드
setupBefore Test.ExecutionEvent.TEST_METHOD
TestExecutionEvent.TEST_EXECUTION
언제 유저가 세팅되는지를 정함

내부에서 UserDetails를 직접 구현해서 Custom User를 만들어 사용하는 경우에는 WithMockUser를 사용하면 문제가 발생할 수 있다.

WithMockUser는 org.springframework.security.core.userdetails.User를 만들어주지만 우리가 필요한 User는 Custom User 이기 때문이다.(class cast 에러 발생할 수 있음)

 

@WithUserDetails

WithMockUser와 마찬가지로 Mock User를 생성하고 Authentication을 만든다.

WithMockUser와 다른 점은 Mock User를 가져올 때 UserDetailsService의 Bean 이름을 넣어줘서 userDetailsService.loadUserByUsername(String username)을 통해 User를 가져온다.

위와 같이 사용하며 내부 속성은 다음과 같다.

맴버변수 예시 설명
value user123 가져올 user의 username
userDetailsServiceBeanName userDetailsService UserDetailsService를 구현한 Bean의 이름
setupBefore TestExecutionEvent.TEST_EXECUTION 언제 유저가 세팅되는지를 정함

 

@WithAnonymousUser

WithMockUser와 동일하지만 인증된 유저 대신에 익명(Anonymous) 유저를 Authentication에서 사용한다.

익명이기 때문에 멤버변수에 유저와 관련된 값이 없다.

맴버변수 예시 설명
setupBefore TestExecutionEvent.TEST_EXECUTION 언제 유저가 세팅되는지를 정함

 

@WithSecurityContext

다른 방식들은 Authentication을 가짜로 만들었다고 하면 WithSecurityContext는 아예 SecurityContext를 만든다.

맴버변수 설명
factory WithSecurityContextFactory를 Implement한 Class를 넣어준다.
setupBefore 언제 유저가 세팅되는지 정함

 

With(user(  ))

다른 방식은 어노테이션 기반인 반면 이 방식은 User를 MockMvc에 주입하는 방법이다.

WithMockUser와 마찬가지로 유저를 생성해서 Principal에 넣고 Authentication을 생성해 준다.

org.springframework.security.test.web.servlet.request.user 를 사용한다.

 

댓글