Careeroza
Propagating User Identity
User Token or Service Token?
| Situation | Send | Why |
|---|---|---|
| order-service reads the user's addresses from user-service | the user's token | user-service applies the user's permissions (only own addresses) |
| order-service charges a payment | service token (client credentials) | only order-service may charge; users must not call payments directly |
| nightly job recalculates seller ratings | service token | there is no user |
| need both (who asked + which service) | token exchange (RFC 8693) | a new token with the user as sub and the service as actor |
Forwarding the User's Token
@Bean
RestClient userServiceClient(RestClient.Builder builder) {
ClientHttpRequestInterceptor bearerRelay = (request, body, execution) -> {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth instanceof JwtAuthenticationToken jwtAuth) {
request.getHeaders().setBearerAuth(jwtAuth.getToken().getTokenValue());
}
return execution.execute(request, body);
};
return builder.baseUrl("http://user-service").requestInterceptor(bearerRelay).build();
}Tip: The security context lives in a ThreadLocal. If you call user-service from @Async code or a CompletableFuture, wrap the executor with DelegatingSecurityContextExecutor so the token travels with the task.