
스프링 시큐리티 테스트
- 인증 인가에 대한 정보가 필요한 경우 사용할 수 있는 어노테이션 정리
@WithMockUser
- 스트에 필요한 인증된 인증 정보를 제공하며 간단한 정보를 기본으로 설정할 수 있게끔 도와준다.
- 미리 인증된 사용자를 만들어놓지 않아도 간단하게 인증이 필요한 메소드를 테스트할 수 있다
- userName, password, role 등을 어노테이션 value를 통해 설정해줄 수 있으며, default value로 username = “user”, password = “password”, role = “USER”가 설정되어 있다
@Test
@WithMockUser
public void test() {
assertThat(demoService.save(new Demo())).isNotNull();
}
@WithAnonymousUser
- 인증되지 않은 사용자를 테스트에서 사용할 때 필요한 어노테이션
- 미인증 인증 정보가 필요할 경우 유용하게 사용될 수 있음
@Test
@WithAnonymousUser
public void test() {
assertThat(demoService.save(new Demo())).isNotNull();
}
@WithUserDetails
- Custom으로 만든 UserDetailsService를 통해 자신이 구현한 방식으로 인증 정보를 가지고 와야 할 필요성이 있는 경우
- 록된 Bean 중 UserDetailsService 찾아 미리 어노테이션에서 설정한 username으로 사용자를 찾는다
- value을 통해 테스트에 필요한 사용자 이름을 지정할 수 있다
- userDetailsServiceBeanName을 통해 직접 사용할 Bean을 지정할 수 있다. 다만 이 Bean은 UserDetailsService를 구현한 Bean이어야 한다
@Test
@WithUserDetails("name")
void test3() {
demoService.print();
}
@WithSecurityContext
- 위 어노테이션들은 실제 UserDetailsService에 등록된 사용자만 사용할 수 있다
- 직접 SecurityContext에 테스트에서 활용할 인증 정보를 넣어줄 때 사용
@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class)
public @interface WithMockCustomUser {
String first() default "first";
String second() default "second";
}
- Factory는 WithSecurityContextFactory interface를 구현해 만들어지며, Generic에 이전에 만든 WithMockCustomUser 어노테이션 클래스를 입력해 사용자가 미리 설정한 value를 사용할 수 있다.
public class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<WithMockCustomUser> {
@Override
public SecurityContext createSecurityContext(WithMockCustomUser customUser) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
CustomUser principal = new CustomUser(customUser.first(), customUser.second(), "ADMIN");
Authentication auth = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(), principal.getAuthorities());
context.setAuthentication(auth);
return context;
}
}
- 위와 같이 구현이 완료되었으면 다른 어노테이션처럼 테스트할 메소드에 Custom 어노테이션을 달기만 하면 된다.
@Test
@WithCustomUser(first = "myName", second = "myPassword")
void test3() {
demoService.print();
...
}
- @WithMockUser, @WithUserDetails, @WithAnonymousUser 모두 @WithSecurityContext를 활용한 어노테이션들이며 미리 구현된 factory를 통해 SecurityContext에 인증 정보를 넣을 수 있었다.
메타 어노테이션
- 어노테이션 value가 중복되어 사용성이 다소 떨어지는 문제가 발생할 수 있다. 이럴 경우 간단히 메타 어노테이션을 활용하여 추가적인 입력을 줄일 수 있다
@Retention(RetentionPolicy.RUNTIME)
@WithMockUser(roles = "ADMIN")
public @interface WithMockAdmin {
}