fix: verify-password·profile 인터셉터 보호 경로 누락 수정
CI / build (push) Failing after 15m51s

- WebConfig authInterceptor 경로에 /api/auth/verify-password, /api/auth/profile 추가
  (누락 시 CURRENT_MEMBER 미설정 → 로그인 사용자도 NPE 500)
- WebConfigTest: 인증 필수 auth 엔드포인트 보호 경로 등록 회귀 가드

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ByungCheol
2026-06-06 14:14:15 +09:00
parent e592c174bf
commit e9a3fc82e5
2 changed files with 52 additions and 0 deletions
@@ -24,6 +24,7 @@ public class WebConfig implements WebMvcConfigurer {
// 인증: 로그인 필요한 경로 (관리자 경로 포함 — SessionUser 세팅용으로 먼저 실행)
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/auth/me", "/api/auth/logout", "/api/auth/password",
"/api/auth/verify-password", "/api/auth/profile",
"/api/board/**", "/api/admin/**", "/api/account/**");
// 인가: 관리자 전용 경로 (authInterceptor 다음에 실행되어 role 검사)
registry.addInterceptor(adminInterceptor)
@@ -0,0 +1,51 @@
package com.sb.web.common.config;
import com.sb.web.auth.web.AdminInterceptor;
import com.sb.web.auth.web.AuthInterceptor;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* 인터셉터 보호 경로 등록 회귀 가드.
* CURRENT_MEMBER 를 쓰는 인증 필수 엔드포인트가 authInterceptor 경로에 빠지면
* 인터셉터가 동작하지 않아 로그인 사용자도 NPE(500)가 난다. (verify-password/profile 누락 사례)
*/
class WebConfigTest {
@Test
@DisplayName("인증 필수 auth 엔드포인트가 모두 보호 경로에 등록된다")
void protectsAuthEndpoints() {
InterceptorRegistry registry = mock(InterceptorRegistry.class);
InterceptorRegistration registration = mock(InterceptorRegistration.class);
when(registry.addInterceptor(any())).thenReturn(registration);
when(registration.addPathPatterns(any(String[].class))).thenReturn(registration);
new WebConfig(mock(AuthInterceptor.class), mock(AdminInterceptor.class)).addInterceptors(registry);
ArgumentCaptor<String[]> captor = ArgumentCaptor.forClass(String[].class);
verify(registration, atLeastOnce()).addPathPatterns(captor.capture());
List<String> allPatterns = new ArrayList<>();
captor.getAllValues().forEach(arr -> allPatterns.addAll(List.of(arr)));
assertThat(allPatterns).contains(
"/api/auth/me",
"/api/auth/logout",
"/api/auth/password",
"/api/auth/verify-password",
"/api/auth/profile");
}
}