Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to propagate credentials between micro services using spring-session

We are using an architecture very similar to the one described in this great guide on spring.io. Our gateway handles authentication, and sessions are stored in Redis using spring-session. Endpoints of our micro services are secured and also use spring-session.

In a micro service I need to call an endpoint of another micro service. I get the URL easily through the discovery client, but I need to provide credentials and I'm not sure of the best way to achieve that.

I am thinking about getting the SESSION cookie from the HttpRequest, store it in some kind of thread local variables or request scope bean, and use it in the RestTemplate to call the second micro service. I need this request scoped bean because the RestTemplate will be used in the service layer, i.e. not in the MVC controller, and I don't want to pollute my service layer methods with this session identifier I get from the cookie.

Is there a better way to approach this need? Is there already some support in Spring Cloud for this?

Thanks a lot for your input

like image 986
lejeune.n Avatar asked Aug 07 '15 10:08

lejeune.n


1 Answers

At this time the easiest way to access the Spring Session id is using RequestContextHolder.getRequestAttributes().getId(). Once you have access to that you can write a custom ClientHttpRequestInterceptor to include the session id in requests:

public SpringSessionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
        boolean isMyService = ...;

        // very important not to send the session id to external services
        if(isMyService) {
            request.getHeaders().add("x-auth-token", RequestContextHolder.getRequestAttributes().getId());
        }
    }
}

Then when you create your RestTemplate make sure to add SpringSessionClientHttpRequestInterceptor.

RestTemplate rest = new RestTemplate();
rest.getInterceptors().add(new SpringSessionClientHttpRequestInterceptor());
like image 106
Rob Winch Avatar answered Oct 15 '22 13:10

Rob Winch