@Test
@DisplayName("해당 게시물에 권한 없는 유저가 질문을 삭제")
@WithMockUser(SecurityContextUtils.ANONYMOUS_USER_ID_STRING)
void unAuthorizedUserDeleteQuestion() throws Exception {
Long targetQuestionId = 1L;
when(questionService.getAuthorId(targetQuestionId)).thenReturn(Long.valueOf(AUTHORIZED_USER));
mvc.perform(delete("/questions/"+ targetQuestionId))
.andExpect(status().isUnauthorized());
}
이러한 상황에서 위의 테스트코드는 fail이다.
실행시켜보면 status가 403이 나온다. (권한있는 유저가 질문을 삭제하는 경우에도 403이 나온다.)
그 이유는 csrf설정을 추가하지 않았기 때문이다.
csrf에 관한 깊은 설명은 다음에 하기로 하고 간단한 설명부터 해보겠다.
csrf(Cross Site Request Forgery)의 동작 원리는
이런식으로 탈취가 일어난다.
우리 사이트에서 발급받은 쿠키는 꽤나 보안적으로 안전하다고 생각했다.
완벽하다고 생각했지만, 도메인 설정 이 완벽하지 않았다. 서브도메인을 다르게하면 고대로 탈취될 수 있기 때문이다.
Spring Security에서 보통 많은 사람들이 csrf 설정을 막는데,
그 이유는 현재 대다수의 통신 방법인 REST api 통신에서는 정보들이 모두 stateless하기 때문이다. 무엇인가 권한이 필요한 요청을 하기 위해서는 요청에 필요한 인증 정보를(OAuth2, jwt토큰 등)을 포함시킨다.
하지만 쿠키를 사용하여 인증하는 경우 csrf설정을 끄면 안된다.
이유를 알고 csrf를 끄자.
아무튼.. 일단 저 테스트는 MvcTest만을 위한것이므로, 기본적으로 csrf설정을 config로 했다고 해도, MvcTest만을 위한 스프링 빈만 주입시켜서, 해당 설정이 주입되지 않는다.
따라서 csrf설정을 해주자.
@Test
@DisplayName("해당 게시물에 권한 없는 유저가 질문을 삭제")
@WithMockUser(SecurityContextUtils.ANONYMOUS_USER_ID_STRING)
void unAuthorizedUserDeleteQuestion() throws Exception {
Long targetQuestionId = 1L;
when(questionService.getAuthorId(targetQuestionId)).thenReturn(Long.valueOf(AUTHORIZED_USER));
mvc.perform(delete("/questions/"+ targetQuestionId)
.with(csrf()))
.andExpect(status().isUnauthorized());
}