[Trouble Shooting] MSA + Spring Secuirty 환경에서 FeignClient 호출 시 403/401 발생 원인과 해결
TL;DR
- FeignClient는 기본적으로 JWT 헤더를 전달하지 않는다.
- 그래서 서비스는 인증 실패(401/403)를 반환한다.
- RequestInterceptor를 사용해 Authorization 헤더를 강제로 전달하면 해결 된다.
배경
프로젝트는 Spring Cloud 기반 MSA 구조로 구성되어 있으며,
각 서비스는 Spring Security + JWT 인증 방식을 사용하고 있습니다.
트러블 슈팅을 만난 서비스는 Brand (업체), Order(주문) 서비스이며, 모든 외부 요청은 게이트웨이가 우선적으로 받습니다.
각 서비스는 내부 통신 시에 FeignClient를 사용합니다.
업체서비스에서는 자신의 업체에 등록되어 있는 상품들을 사용자들이 주문을 하였을 때 주문 내역과, 상품 준비를 할 수 있게 조회를 할 수 있는 대시보드를 만드는 과정이었으며, 주문 서비스의 내부 API /internal/v1/orders/items 를 호출하게 됩니다.
각 서비스는 JWT 기반 인증을 진행하고 있으며 인증 사용자 정보를 기반으로 권한 검증도 수행합니다.
이슈
브랜드 서비스에서 주문 서비스로 FeignClient 통신을 시도할 때 오류가 발생했습니다.
403 Forbidden
401 Unauthorized
FeignException : "인증이 필요합니다"
브랜드 서비스에서 인증된 사용자 상태인데, 주문 서비스에서는 인증 실패로 처리되었습니다.
원인
JWT 인증 정보가 내부 서비스로 전달되지 않았기 때문이었습니다.
1) FeignClient는 HTTP 헤더를 자동으로 전달하지 않는다고 합니다.
Spring Security 가 인증한 사용자의 JWT는 현재 컨트롤러 레벨에서만 존재하고,
Feign 호출 시에는 자동으로 다음 서비스로 전달되지 않는다고 합니다.
따라서, 주문 서비스는 JWT가 없는 요청을 받으므로 인증 실패 401에러 또는 403이 발생했습니다.
2) 주문 서비스는 내부 API라도 Security Filter 를 통과해야 합니다.
httpSecurity.authorizeHttpRequests(authorize -> {
authorize.anyRequest().authenticated();
});
주문 서비스 시큐리티 설정 일부분 인데, 어떠한 요청이라도 인증 인가 없이는 통과되지 못하게 작성을 하지 않았습니다.
따라서 내부 API도 반드시 인증된 JWT가 필요했고, Feign이 JWT를 전달하지 않았기 때문에 보안 필터에서 막힌 것입니다.
문제
JWT나 Authorization 헤더가 전달되지 않으면 서비스는 인증된 사용자로 인식되지 않는 문제가 있습니다.
-> Security Context에 Authentication이 생성되지 않습니다.
위에서 발생한 401/403이 발생하고, 주문 서비스에서 "인증이 필요하다는" 에러가 반환됩니다.
해결 방안
Feign 호출 시 Authorization 헤더(JWT)를 전달해주는 것입니다.
Spring Cloud OpenFeign에서 이를 해결하려면 RequestInterceptor를 이용해서 직접 헤더를 복새해야 합니다.
@Configuration
public class FeignAuthConfig {
@Bean
public RequestInterceptor requestInterceptor() {
return requestTemplate -> {
ServletRequestAttributes attrs =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attrs == null) return;
String token = attrs.getRequest().getHeader("Authorization");
if (token != null && !token.isBlank()) {
requestTemplate.header("Authorization", token);
}
};
}
}
그리고, FeignClient를 사용하는 클래스
@FeignClient(
name = "order-service",
configuration = FeignAuthConfig.class
)
public interface OrderClient {
@GetMapping("/internal/v1/orders/items")
List<OrderItemForBrandResponse> getItemsForBrand(@RequestParam UUID brandId);
}
결과
- FeignClient 통신 시 Authorization 헤더가 정상적으로 전달 됨.
- 주문 서비스 Security 필터가 JWT를 문제없이 파싱함
- 더 이상 401/403 인증 실패 발생하지 않음.
- 서비스 간 권한 흐름이 안정적으로 유지됨
etc) 시퀀스 다이어그램

요약
| 항목 | 내용 |
| 문제 원인 | FeignClient 가 기본적으로 Authorization 헤더를 전달하지 않기 때문 |
| 증상 | 내부 서비스 호출 시 401 또는 403 발생, 인증 필요 메시지 출력 |
| 핵심 해결책 | Feign RequestInterceptor 로 JWT 헤더를 복사하여 전달 |
| 결과 | 인증/인가 성공, @AuthenticationPrincipal 정상 주입 |
'BACKEND & SERVER > Trouble Shooting' 카테고리의 다른 글
| [Trouble Shooting] Kafka Connect No suitable driver found (0) | 2025.11.21 |
|---|---|
| [Trouble Shooting] Spring Cloud Gateway 순환 참조 (0) | 2025.11.08 |
| [Thouble Shooting] CORS (0) | 2025.11.05 |
