Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Zuul
- 플로이드 와샬
- 도커
- 트리
- 구간 트리
- 이분 탐색
- 유레카
- 다익스트라
- Java
- 스프링 시큐리티
- 이분 매칭
- Spring Cloud Config
- BFS
- 주울
- 완전 탐색
- 달팽이
- 메모이제이션
- Logback
- spring cloud
- 비트마스킹
- 게이트웨이
- 스택
- 구현
- 서비스 디스커버리
- Gradle
- 백트래킹
- ZuulFilter
- docker-compose
- spring boot
- dp
Archives
- Today
- Total
Hello, Freakin world!
스프링 시큐리티, 스프링 MVC 통합 테스트 작성하기 본문
간단하게 몇 개의 url 접근에 필요한 권한을 설정하고 mock 테스트를 작성해보자.
아래와 같이 url 권한을 설정, 요청에 csrf 토큰을 추가하도록 설정했다.
csrf 설정을 하게 되면 위험할 수 있는 요청(POST, DELETE, PUT)의 경우 반드시 csrf 토큰을 요청에 포함해야 된다.
WebSecurityConfig
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(HttpMethod.POST,"/member/csrf").hasAnyRole("USER", "ADMIN")
.antMatchers(HttpMethod.POST,"/member/user").hasRole("USER")
.antMatchers(HttpMethod.POST,"/member/admin").hasRole("ADMIN")
.antMatchers(HttpMethod.GET,"/member/**").hasRole("USER")
.anyRequest().authenticated()
.and()
.csrf();
// .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
}
}
컨트롤러 메서드도 만들어 주고~
MemberRestController
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
public class MemberRestController {
private final MemberRepository memberRepository;
@PostMapping("/member/csrf")
public String postCsrf() {
return "csrf";
}
@PostMapping("/member/user")
public String postWithUserRole() {
return "with USER role";
}
@PostMapping("/member/admin")
public String postWithAdminRole() {
return "with ADMIN role";
}
@GetMapping("/member")
public String get() {
return "get";
}
}
이와 같은 mvc 요청들을 스프링 시큐리티와 연계해서 어떻게 테스트할 수 있을까?
다행히도 스프링 시큐리티에서 편리한 방법들을 제공해준다.
우선, spring-securirt-test 의존성을 추가하자.
testImplementation 'org.springframework.security:spring-security-test'
이제 테스트를 작성해보자.
테스트는 MockMvc를 이용한다.
중요한 부분은 MockMvc 인스턴스를 초기화하는 부분이다.
클래스 레벨에 @SpringbootTest 와 @WebConfuguration 이 붙은 것도 주의!
(공식 레퍼런스에는 다르게 나와있는데 이거 때문에 몇 시간동안 헤맸다...)
그리고 또 중요한 부분은 SecurityMockMvcRequestPostProcessors 의 메서드를 이용해
필요한 보안 관련 부분을 처리하는 점.
이 두 가지만 알면 된다. 나머지 보안 관련 테스트는 맨 밑의 공식 레퍼런스를 참고하자.
다른 방식도 크게 다르지 않다.
MemberRestControllerTest
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@WebAppConfiguration
public class MemberRestControllerTest {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@BeforeEach
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.alwaysDo(print())
.apply(springSecurity())
.build();
}
@WithMockUser(roles = {"USER", "ADMIN"})
@Test
public void testPost() throws Exception {
mvc.perform(post("/member/csrf")
.characterEncoding("UTF-8")
.with(csrf()))
.andExpect(status().isOk())
.andExpect(content().string("csrf"));
}
@Test
public void postWithUserRoleTest() throws Exception {
mvc.perform(post("/member/user")
.characterEncoding("UTF-8")
.with(csrf())
.with(user("mockUsername").roles("USER")))
.andExpect(status().isOk())
.andExpect(content().string("with USER role"));
}
@Test
public void postWithAdminRoleTest() throws Exception {
mvc.perform(post("/member/admin")
.characterEncoding("UTF-8")
.with(csrf())
.with(user("mockUsername").roles("ADMIN")))
.andExpect(status().isOk())
.andExpect(content().string("with ADMIN role"));
}
@WithMockUser(roles = "USER")
@Test
public void testGet() throws Exception {
mvc.perform(get("/member")
.characterEncoding("UTF-8")
.with(user("my").roles("USER")))
.andExpect(status().isOk());
}
}
'Spring boot > Security' 카테고리의 다른 글
스프링 시큐리티 CORS 해결하기 (0) | 2021.04.19 |
---|---|
[스프링 시큐리티] Username/Password 인증 구현하기 (0) | 2021.04.17 |
DelegatingPasswordEncoder 단위테스트 케이스 (0) | 2021.04.11 |
Comments