#web-services #ssl #spring-integration #dynamic-url
#веб-сервисы #ssl #spring-интеграция #динамический URL
Вопрос:
Я создаю службу, которая взаимодействует с несколькими устройствами, используя SOAP через https. Эти устройства предоставляют один и тот же API веб-сервиса (тот же wsdl). Новые устройства могут быть добавлены в эту схему в любое время во время выполнения.
Мне нужно динамически запрашивать каждое из этих устройств и любые, которые могут быть добавлены в будущем. Каждое из этих устройств имеет самозаверяющий сертификат для ssl. Служба, которую я создаю, должна быть реализована с использованием Spring Integration.
Учитывая вышесказанное, у меня есть два основных вопроса:
- В интеграции Spring как я могу динамически во время выполнения назначить uri сервиса.
- Как мне доверять всем сертификатам.
Любая помощь была бы высоко оценена.
Комментарии:
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}"