шлюз исходящих веб-сервисов Spring интеграции с динамическим uri и доверием ко всем сертификатам

#web-services #ssl #spring-integration #dynamic-url

#веб-сервисы #ssl #spring-интеграция #динамический URL

Вопрос:

Я создаю службу, которая взаимодействует с несколькими устройствами, используя SOAP через https. Эти устройства предоставляют один и тот же API веб-сервиса (тот же wsdl). Новые устройства могут быть добавлены в эту схему в любое время во время выполнения.

Мне нужно динамически запрашивать каждое из этих устройств и любые, которые могут быть добавлены в будущем. Каждое из этих устройств имеет самозаверяющий сертификат для ssl. Служба, которую я создаю, должна быть реализована с использованием Spring Integration.

Учитывая вышесказанное, у меня есть два основных вопроса:

  1. В интеграции Spring как я могу динамически во время выполнения назначить uri сервиса.
  2. Как мне доверять всем сертификатам.

Любая помощь была бы высоко оценена.

Комментарии:

1. «Как я могу доверять всем сертификатам …» — Это может быть плохой идеей. Вы говорите об Оппортунистическом шифровании или оппортунистической безопасности ? Если это так, вы могли бы также использовать Анонимный Диффи-Хеллман (ADH) и избегать всех сертификатов вместе взятых.

Ответ №1:

Спасибо за вашу помощь Гэри и Артему.

Я смог решить проблему динамического uri с помощью локальной переменной потока и SPEL.

Для доверия самоподписанных сертификатов я внедрил и нового отправителя сообщений с использованием httpclient. HttpClient предоставляет стратегию TRUSTSELFSIGNED. Я использовал это, чтобы доверять всем самоподписанным сертификатам. Решения, похоже, работают. Ниже приведен код, если у кого-то возникнут подобные потребности в будущем.

     KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());

    InputStream instream = getClass().getResourceAsStream(trustStoreFile);

     try {
        trustStore.load(instream, trustStorePassword.toCharArray());
    } finally {
        instream.close();
    }

    SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
    SSLContext sslcontext = builder.build();

    SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    HttpClientBuilder httpClientBuilder = HttpClients.custom();
    httpClientBuilder.setSSLSocketFactory(sslsf);
    httpClientBuilder.addInterceptorFirst(new RemoveSoapHeadersInterceptor());

    if (credentials!=null){
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY,credentials);
        httpClientBuilder.setDefaultCredentialsProvider(credsProvider);
    }

    CloseableHttpClient closeableHttpclient = httpClientBuilder.build();
    setHttpClient(closeableHttpclient); 
  

Комментарии:

1. эй, не могли бы вы рассказать немного больше о том, как / где вы используете этот код?

Ответ №2:

Первый вопрос прост; смотрите документацию XSD:

 The Destination URI for this Web Service Gateway. If the URI should be determined at runtime
(e.g. registry lookup), then configure a 'destination-provider' reference instead. Aternatively,
this URI may include {placeholders} whose values are determined by evaluating SpEL expressions
provided via 'uri-variable' sub-elements. The root object for those evaluations is the actual
request Message at runtime, i.e. you can access its payload or headers in the expression.
  

и документация о заполнителях URI.

Я не знаю, можете ли вы динамически добавлять ключи / сертификаты в хранилище ключей / truststore во время выполнения; Я никогда не пробовал.

Комментарии:

1. Спасибо, Гэри! Мне нужно изменить uri во время работы службы, чтобы я мог подключаться к разным устройствам. Насколько я понимаю опубликованный вами абзац, uri может быть «вычислен» один раз, но впоследствии не может быть изменен, чтобы указывать на другой uri во время работы службы. Правильно ли я это понял?

2. Нет; он оценивается для каждого сообщения. В случае конечного поставщика API ( getDestination() ) не предоставляет никакого контекста, поэтому вам придется передать некоторый контекст пользовательской реализации, используя ThreadLocal или аналогичный. Использование переменных uri проще — переменные оцениваются на основе сообщения при его отправке. Опять же, смотрите раздел 31.4 по ссылке в моем ответе. uri=http://{host}/{path} .

3. Вы можете создать uri руководство где-нибудь выше по потоку или просто извлечь его из headers и иметь только один uri variable uri="{uri}"