👾 문제식별
스프링시큐리티를 공부를 시작했다.
처음으로 배운 특정 url만 접근 권한을 주고 나머지는 허용하지 않는 걸 어플리케이션에 적용해보았다.
루트와 '/notebook' 만 접속이 가능하게 해놓았다.

테스트 겸 기존에 짜놓았던 테스트 코드를 실행해보았는데 오잉 401 오류가 뜨면서 테스트가 실패한다.

postman으로 외부에서 다시 호출해보았더니 200으로 정상 작동한다.
작성한 테스트 코드의 문제일 가능성이 높아진다.
🔍 원인분석
가벼운 테스트 코드환경을 위해 @WebMvcTest으로 컨트롤러 테스트를 작성하고있는데
@WebMvcTest는 스프링MVC와 관련된 정보만 bean으로 생성되고 나머지는 필요에 따라 주입해야한다고 알고있다.
혹시 스프링시큐리티가 생성되지않아서 그런걸까..?
그렇게 생각하면 401 오류가 발생하는 게 이해되지 않는다. 그럼 아무런 인증검사 없이 api호출이 정상적으로 이뤄져야 할텐데 말이다.
검색하다가 발견한 좋은 글
[Springboot] @WebMvcTest - Controller Test에서 401과 데이트했다.
우리 결혼했어요.
velog.io
동일한 문제를 겪으셨고 이를 해결한 내용을 작성하셨다.
해당 블로그 글을 참고하자면

By default, tests annotated with
@WebMvcTest will also auto-configure Spring Security and MockMvc (include support for HtmlUnit WebClient and Selenium WebDriver).
For more fine-grained control of MockMVC the @AutoConfigureMockMvc annotation can be used.
기본적으로 @WebMvcTest에는 자동설정된 스프링 시큐리티와 MockMvc가 따라오고, 좀 더 MockMvc의 설정을 변경하고 싶다면 @AutoConfigureMockMvc 어노테이션을 사용하면 된다고 한다.
자동으로 설정된 스프링 시큐리티는 어떤 상태일까?

SpringBootWebSecurityConfiguration 클래스의 일부인데, 보면 anyRequest가 인증을 필요로 하고 있다.
모든 요청에 대해서 인증을 필요로 한다는 얘기였다.
그래서 내 설정과 다르게 401 오류가 났었구나~
🤔 해결방법시도
요청 시에 권한을 함께 넘겨주는 방법은 세 가지가 있다.
1) ExcludeFilter를 이용해 Security를 회피하는 방법
2) @WithMockUser, @WithUserDetails 등의 Annotation을 이용해 권한을 함께 요청하는 방법
3) @TestConfiguration 파일을 별도로 설정하는 방법
1번은 사실 인증을 회피하는 것이고, 3번을 하기에는 인증 테스트가 필요해서 만든 테스트코드가 아니라면 조금 번거롭다고 생각한다.
그래서 2번 방법으로 시도해보았다.
대표적인 유저 테스트를 위한 어노테이션들은 아래와 같다
- @WithMockUser - 인증된 사용자
- @WithAnonymousUser - 미인증 사용자 (principal에서 "anonymous"가 들어가있음)
- @WithUserDetails - 메서드가 principal 내부의 값을 직접 사용하는 경우 (별도의 사전 설정 필요)
@WithMockOAuth2User 모의 OAuth2 사용자를 생성하는 어노테이션도 있는데, 관련한 테스트를 해볼때 한번 써봐야겠다.
암튼, 나는 단순 조회 api를 위한 테스트이니 @WithMockUser를 사용하여 자동으로 인증처리를 해주었다.
✅ 최종해결방법

💡 해결 방법 설명
@WithMockUser을 사용하려면 Dependency추가가 필요하다.
testImplementation ("org.springframework.security:spring-security-test")
gradle에 추가 후 필요한 테스트코드에 @WithMockUser 어노테이션을 갖다 쓸 수 있다.
'개발 공부 > 트러블슈팅' 카테고리의 다른 글
AWS EC2 상태검사가 1/2만 검사 통과 상태 일때 (0) | 2024.10.24 |
---|---|
@OneToMany 관계 정의 후, getter 호출 시 NullPointerException이 발생하는 원인과 문제 해결 (0) | 2024.09.29 |
H2 datasource 정보 입력이후, NullPointerException이 발생하는 원인과 해결방법 (2) | 2024.09.14 |
@Valid 가 작동하지 않는 원인과 해결방법 (0) | 2024.08.26 |
@RequestBody로 객체를 받을 때 @Builder만 있으면 발생하는 400 에러 원인과 해결방법 (0) | 2024.08.25 |