Лучший способ распространения учетных данных между микрослужбами с помощью spring-session


Мы используем архитектуру, очень похожую на ту, что описана в этом замечательном руководстве по spring.io . наш шлюз обрабатывает аутентификацию, и сеансы хранятся в Redis с помощью spring-session. Конечные точки наших микроуслуг защищены и также используют весеннюю сессию.

В микрослужбе мне нужно вызвать конечную точку другой микрослужбы. Я легко получаю URL-адрес через клиент обнаружения, но мне нужно предоставить учетные данные, и я не уверен в лучшем способе достижения тот.

Я думаю о том, чтобы получить файл cookie сеанса из HttpRequest, сохранить его в какой-то локальной переменной потока или Бобе области запроса и использовать его в RestTemplate для вызова второй микрослужбы. Мне нужен этот боб с областью действия запроса, потому что RestTemplate будет использоваться на уровне сервиса, то есть не в контроллере MVC, и я не хочу загрязнять мои методы уровня сервиса этим идентификатором сеанса, который я получаю из файла cookie.

Есть ли лучший способ подойти эта потребность? Есть ли уже какая-то поддержка в весеннем облаке для этого?

Большое спасибо за Ваш вклад

1 3

1 ответ:

В настоящее время самый простой способ получить доступ к идентификатору весенней сессии-это использовать RequestContextHolder.getRequestAttributes().getId(). После того, как у вас есть доступ к нему, вы можете написать пользовательский ClientHttpRequestInterceptor, чтобы включить идентификатор сеанса в запросы:

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());
        }
    }
}

Затем, когда вы создадите свой RestTemplate, обязательно добавьте SpringSessionClientHttpRequestInterceptor.

RestTemplate rest = new RestTemplate();
rest.getInterceptors().add(new SpringSessionClientHttpRequestInterceptor());