Consider users sending requests to service A, which then implements business logic that includes submitting multiple requests to services B, C etc.
Service A is implemented using a RestController, which receives certain headers (e.g. Authorization) from users.
Service A then submits requests to services B, C etc. using a RestTemplate bean.
How does one make it automatically forward service A RestController headers with any requests submitted via the RestTemplate bean to services B, C etc.?
The goal here is to avoid specifying these headers explicitly on every RestTemplate request. The ultimate goals are:
- Enable a zero-trust microservice architecture, where all requests between internal services are authenticated.
- Preserve authenticated user context for all requests from (1).
- Do it with the least amount of change possible.
I've heard recommendations using Zuul or similar proxies for such things, but wanted to confirm if this is the best/most common/suitable approach for this particular scenario. What makes me pause on it is that service A is not a simple "proxy" service that just forwards requests on different routes, but rather a rich REST API that needs to "use" other services, rather than simply forward/enrich incoming requests. So I'm not sure if Zuul or other proxies would be fully suitable for it.
To make it a bit more concrete, I'd like to avoid having to modify logic like this:
@GetMapping("/baz")
public Baz getBaz() {
final Foo foo = restTemplate.getForObject("http://service-b/foo", Foo.class)
final Bar bar = restTemplate.getForObject("http://service-c/bar/{barId}", Bar.class, foo.getBarId());
return bar.getBaz();
}
While one could replace restTemplate.getForObject(...) with: restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(req.getHeaders()), Response.class, param), doing so is undesirable for services with many API calls.
Alternatively, doing so via a ClientHttpRequestInterceptor would only be possible if were able to access GetMapping's per-request header inside the interceptor.
Any concrete examples would be much appreciated!
Update: I may have found answers to similar questions here and here. Looks like the missing pieces have been RequestContextHolder.currentRequestAttributes() for MVC and subscriberContext for WebFlux.