이전 포스트: SecurityConfig 엔드포인트 권한 설정
문제 개요
오류 상황과 영향 범위 (예: 특정 코드 실행 시 발생, 특정 라이브러리 버전 호환 문제 등) 발생 배경 (예: 코드 테스트 중, 배포 중 문제 발견 등)
오류 상황과 영향 범위
- JwtAuthenticationFilter 적용 후 인증/인가 설정 과정에서 로그인 후 댓글 작성, 수정, 삭제, 좋아요 등의 특정 엔드포인트만 허용하려 했으나, 다른 API 경로까지 접근이 차단되는 문제가 발생
발생 배경
- JwtAuthenticationFilter 및 SecurityConfig 설정 중 JWT 기반 인증 및 인가 기능을 테스트하는 과정에서 특정 엔드포인트가 예상치 않게 차단된 문제 발견
오류 메시지 및 원인 분석
오류 코드, 오류 메시지 포함 HTTP 상태 코드, 애플리케이션 로그, 서버 로그 등 구체적인 오류 정보 정리 및 로그 메시지를 통한 분석 제공 문제 발생 원인에 대한 심층 분석
오류 코드 및 메시지
{
"timestamp": "2025-05-05T02:49:02.048+00:00",
"status": 401,
"error": "Unauthorized",
"path": "/api/v1/posts/2/comments"
}
분석 과정
- JwtAuthenticationFilter 적용으로 인해, 설정하지 않은 엔드포인트에 대해서도 인증 및 인가 로직이 동작하여 모든 요청에 대해 일괄적으로 차단되는 현상이 발생하였다.
- SecurityConfig의 authorizeHttpRequests 설정에서 잘못된 경로 지정으로 인해 필터링이 예상대로 동작하지 않았다.
해결 및 고민 과정
처음 문제를 접했을 때 고려했던 대안들과 선택하지 않은 이유 실험적으로 적용한 방법이 실패한 사례와 그 이유 여러 해결책 중 최적의 방안을 선택한 과정
초기 고려한 대안
- SecurityConfig의 authorize 설정 경로를 명확하게 분리하여 지정
- JwtAuthenticationFilter의 shouldNotFilter 메소드를 세부적으로 조정하여 특정 경로 제외
최종 해결책 및 구현
문제 해결을 위한 단계별 조치 방법과 코드 예시 (예: 특정 애노테이션 추가, 라이브러리 버전 조정, 설정 변경 등) 참고 자료 (관련 공식 문서, 개발자 커뮤니티 게시물 등)
// 엔드포인트별 권한 설정
.authorizeHttpRequests(authorize ->
authorize
// 모든 HTTP 메소드에 대해 인증 없이 접근 가능한 경로
.requestMatchers(getPublicEndpoints().toArray(String[]::new)
).permitAll()
// 댓글 GET 요청 허용
.requestMatchers(HttpMethod.GET, "/api/v1/posts/*/comments")
.permitAll()
// 회원 권한
.requestMatchers(getPubliCUserEndpoints().toArray(String[]::new)).hasRole("USER")
// 관리자 권한
.requestMatchers(getPublicAdminEndpoints().toArray(String[]::new)).hasRole("ADMIN")
// 그 외 모든 요청 허용
.anyRequest().permitAll()
);
기존 권한 설정에서
// 엔드포인트별 권한 설정
.authorizeHttpRequests(authorize ->
authorize
// — USER 로그인 필요
.requestMatchers(HttpMethod.POST, "/api/v1/posts/*/comments").authenticated()
.requestMatchers(HttpMethod.PATCH, "/api/v1/comments/*").authenticated()
.requestMatchers(HttpMethod.DELETE, "/api/v1/comments/*").authenticated()
.requestMatchers(HttpMethod.POST, "/api/v1/comments/*/like").authenticated()
// 그 외 모든 요청 허용
.anyRequest().permitAll()
);
방식으로 권한 설정 수정 후 JwtAuthenticationFilter에서
// 필터 체인 통과
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String path = request.getServletPath();
String method = request.getMethod();
// Auth 관련 엔드포인트 ⇒ 무조건 스킵
if (List.of(
"/api/v1/auth/login",
"/api/v1/auth/signup",
"/api/v1/auth/refresh"
).contains(path)) {
return true;
}
// “댓글 쓰기·수정·삭제·좋아요” 만 필터 적용
boolean isCommentWriteEndpoint =
("POST".equals(method) && path.matches("^/api/v1/posts/\\\\d+/comments$")) // 댓글 작성
|| ("PATCH".equals(method) && path.matches("^/api/v1/comments/\\\\d+$")) // 댓글 수정
|| ("DELETE".equals(method) && path.matches("^/api/v1/comments/\\\\d+$")) // 댓글 삭제
|| ("POST".equals(method) && path.matches("^/api/v1/comments/\\\\d+/like$")); // 댓글 좋아요
// isCommentWriteEndpoint 이면 필터 동작(= false 리턴), 아니면 스킵(= true 리턴)
return !isCommentWriteEndpoint;
}
에 대한 내용을 추가하여 필터 적용을 함
결과 및 성능 분석
개선 후 응답 속도, DB 부하 감소 수치 등 구체적인 데이터 포함 문제 해결 전/후 성능 비교 그래프나 로그 분석 내용 포함 이슈 트래킹 및 자동화 방안 추가 (내부 개발자가 반복적인 문제 해결을 효율적으로 관리할 수 있도록 가이드 제공)
개선 후 결과
- 의도한 엔드포인트만 인증 및 인가가 요구되고 나머지 API 경로는 정상적으로 접근 가능하게 설정됨.
추가 개선점
유사한 문제를 방지하기 위한 주의할 점 (예: 애노테이션 명시 여부, 프레임워크 업데이트 주기 확인 등) 문제 해결 과정에서 배운 점 및 중요한 교훈 공유 보안 고려 사항 추가 (해결 과정에서 발생할 수 있는 보안 리스크 및 예방 조치 포함)
주의할 점
- Spring Security 설정 시 requestMatchers 경로 및 순서의 정확한 관리 필요
- JwtAuthenticationFilter 적용 범위를 최소한으로 제한하여 불필요한 인증 로직 수행 방지
보안 고려 사항
- 인증이 불필요한 경로는 명확히 설정하여 보안 취약점 발생 가능성을 최소화하고, 모든 설정 변경은 철저한 보안 리뷰 과정을 거쳐야 한다.
'kkokkio - 프로젝트 > 트러블슈팅' 카테고리의 다른 글
테스트코드에서 서킷 브레이커 때문에 머리가 브레이크되다 (3) | 2025.06.16 |
---|---|
SecurityConfig 엔드포인트 권한 설정 (2) | 2025.06.16 |
@Transactional(readonly=true)가 꼭 필요한가? (0) | 2025.06.16 |
DataGrip에서 RDS(MySQL)에 SSH 터널로 안전하게 접속하기 (0) | 2025.06.16 |
사용자 인증/인가 흐름v1.0을 이해하고 RBAC 적용하기 (2) | 2025.06.16 |