github 링크: https://github.com/hyuham1335-stack/spring-advanced.git
GitHub - hyuham1335-stack/spring-advanced
Contribute to hyuham1335-stack/spring-advanced development by creating an account on GitHub.
github.com
1. Sping Security 의존성 추가 문제
ArgumentResolver 관련 문제의 예상 원인을 처리하고 해당 문제가 해결되었는지 postman 을 통하여 요청을 날리는 과정에서 계속해서 Unauthorized 에러가 발생하고 어떠한 디버그 포인트에도 걸리지 않는 문제가 있었다. 또한 빌드 로그에서
Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
This generated password is for development use only. Your security configuration must be updated before running your application in production.
이와 같이 스프링이 자체적으로 보안 비밀번호를 생성했다는 메세지만 출력되고 있었다.
이에 대하여 문제점을 확인한 결과
@Configuration
@RequiredArgsConstructor
public class FilterConfig {
private final JwtUtil jwtUtil;
private final ObjectMapper objectMapper;
@Bean
public FilterRegistrationBean<JwtFilter> jwtFilter() {
FilterRegistrationBean<JwtFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new JwtFilter(jwtUtil, objectMapper));
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
해당 필터 설정클래스를 통해 Spring Security 필터 체인이 아닌 별도의 필터 체인에 JwtFilter 를 등록했음에도 불구하고, Spring Security 의존성을 추가하여 기본적인 보안 필터 체인이 생겨버려서 해당 필터 체인에서 나의 요청이 인가되지 못하였던 것이다.
위에서의 스프링이 생성해준 security password도 보안 필터 체인을 만들어놓고 아무런 설정을 하지않으니 스프링에서 자체적으로 최소한의 보안조치를 위해 만들어준 임시 비밀번호였던 것이었다.
2. ArgumentResolver
@Override
public Object resolveArgument(
@Nullable MethodParameter parameter,
@Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
@Nullable WebDataBinderFactory binderFactory
) {
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
Long userId = (Long) request.getAttribute("userId");
String email = (String) request.getAttribute("email");
UserRole userRole = UserRole.of((String) request.getAttribute("userRole"));
return new AuthUser(userId, email, userRole);
}
예전에 잠깐 보고 넘어갔던 argumentResolver 의 구조를 이번에 다시 한번 보게 되면서 resolverArgument 메서드에 대하여 궁금한 점이 생겨서 이에 대하여 알아보았다.
- 사용하지 않는 파라미터들을 받는 이유는?
ModelAndViewContainer, WebDataBinderFactory 등의 경우에는 Rest API 환경에서의 커스텀 ArgumentResolver 에서는 거의 사용하지 않는다고 한다. 그럼에도 resolveArgument 메서드의 시그니처상 필수로 받아야해서 위와 같이 파라미터로 받도록 작성한다고 한다.
- HttpServlerRequest를 파라미터로 직접 받지 않고 굳이 NativeWebRequest를 받아서 이를 형변환 하는 이유는?
HttpServletRequest 는 서블릿 기술 전용의 객체이기 때문에, 서블릿 기술에 종속되지 않고 다양한 웹 기술에서 사용될 수 있도록 HttpServletRequest 를 상위 추상화 타입인 NativeWebRequest로 대신 받는 것이다. NativeWebRequest 는 HttpServletRequest 의 래퍼 클래스와 같은 방식으로 동작한다.
3. @InjectMocks
@ExtendWith(SpringExtension.class)
public class PasswordEncoderTest {
@InjectMocks
private PasswordEncoder passwordEncoder;
...
}
테스트 코드를 보던 도중에 왜 PasswordEncoder 테스트의 경우 PasswordEncoder 를 new 를 통해 직접 생성하지 않고 @InjectMocks 를 사용하여 객체를 주입받는 것인지 궁금증이 생겼다.
이에 대하여 알아본 결과, 해당 상황에서는 실제로 new 를 통해 직접 객체를 생성해도 큰 문제는 없으나, 추후에 PasswordEncoder 내부에 필드가 추가될 경우,
@InjectMocks 을 사용하여 객체의 생성을 Mokito에 위임하였다면 단순히 추가된 필드의 객체를 @MOCK 을 통해 코드에 추가하면 되지만, 직접 new를 통하여 객체를 생성한 경우에는 추가된 필드의 객체를 포함해서 객체 생성부분의 코드를 직접 다 수정해야한다는 문제점이 존재한다.
따라서, 단위 테스트의 대상이 되는 클래스의 객체는 @InjectMocks 을 사용하여 객체 생성 위임 + @Mock 객체 주입을 받고, 나머지 의존성이 필요한 객체들은 전부 @Mock을 통해 가짜 객체로 대체 하는 것이 좋다.
'트러블슈팅' 카테고리의 다른 글
| 스프링 plus 프로젝트 리팩토링 (0) | 2026.03.04 |
|---|---|
| 클라우드 아키텍쳐 설계 & 배포 (0) | 2026.02.03 |
| 권한 처리 전략 (0) | 2026.01.21 |
| 커맨드 라인 러너 (commandLine Runner) (0) | 2026.01.20 |
| 스케줄, 일정, 유저 관리 앱 Postman (0) | 2026.01.12 |