각 Resource Server는 Access Token을 필요로 합니다. 따라서 하나의 Resource Server에서 또 다른 Resource Server로 요청을 보내려면 그 요청의 Header에 Authorization을 추가해주어야 합니다.
MSA에서는 Resource Server 간 요청이 빈번한데, 개발자가 매번 이 작업을 해주는 것은 비효율적인 일이므로 air-common-lib에서 이를 처리하려 합니다.
이하 본문에서는 Resource Server → Resource Server 요청을 서비스간 요청이라고 하고, Client → Resource Server를 클라이언트 요청이라고 칭하겠습니다.
이를 위해 필요한 작업을 크게 두 가지로 나누면,
- 클라이언트 요청이 들어오면, 요청의 Header에 있는 값을 ThreadLocal에 저장하기.
- 서비스 간 요청 시에, 요청에 ThreadLocal에 있는 값을 Header에 싣기.
클라이언트 요청의 Header에 있는 값을 ThreadLocal에 저장하기 위해 3가지 클래스를 생성했습니다. (UserContext, UserContextHolder, UserContextFilter)
서비스 간 요청을 하기 위한 API는 RestTemplate, Feign가 있는데 아래에서 하나씩 다뤄보도록 하겠습니다.
1. RestTemplate
spring-boot-starter-web에 내장되어 있는 RestTemplate을 바로 이용하는 것이 아니라, 해당 요청에 Interceptor를 추가해 줍니다.
@Bean
fun oauthRestTemplate(): RestTemplate = RestTemplateBuilder().build().apply {
interceptors.add(UserContextInterceptor())
}
그 Interceptor는 UserContextHolder에 저장해놓은 값들을 요청의 Header에 추가하는 역할을 합니다.
class UserContextInterceptor : ClientHttpRequestInterceptor {
override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse = with(request.headers) {
add(UserContext.AUTHORIZATION, UserContextHolder.getContext().authorization)
add(UserContext.CORRELATION_ID, UserContextHolder.getContext().correlationId)
execution.execute(request, body)
}
}
2. Feign
1. Feign을 사용하기 위해 의존성을 추가해야 한다.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
2.Feign도 RestTemplate과 동일하게, Interceptor를 추가해줌으로써 ThreadLocal에 저장한 값을 서비스 간 요청의 Header에 싣습니다.
spring-cloud-starter-feign에 있는 RequestInterceptor를 구현하면, 자동적으로 Interceptor로 등록됩니다.
@Component
class CommonRequestInterceptor : RequestInterceptor{
override fun apply(requestTemplate: RequestTemplate) {
requestTemplate.header(UserContext.AUTHORIZATION, UserContextHolder.getContext().authorization)
requestTemplate.header(UserContext.CORRELATION_ID, UserContextHolder.getContext().correlationId)
}
}
3. 마지막으로, Fegin을 사용할 Resource Server에서 FeginClient임을 명시해줍니다. (Main class)
@SpringBootApplication(scanBasePackages = ["kr.sys4u.lab.airmongoprototype", "kr.sys4u.lab.aircommonlib"])
@EnableFeignClients
class AirMongoPrototypeApplication
'Infra System' 카테고리의 다른 글
Resource Server Setting at Prototype app (0) | 2020.10.14 |
---|---|
Prometheus와 Grafana 연동 - Web UI Dashboard (0) | 2020.10.14 |
Grafana installation - Web UI Dashboard (0) | 2020.10.14 |
Prometheus install - Web UI Dashboard (0) | 2020.10.14 |
Authentication Server - Outer Architecture (0) | 2020.10.14 |
댓글