Метро JAX-WS, как перехватить правильное зашифрованное / подписанное сообщение с недопустимыми символами / несоответствием подписи - PullRequest
0 голосов
/ 14 мая 2019

Мой вопрос очень связан с этим

Я потратил недели головных болей, чтобы попытаться бороться с этим, но, похоже, не существует решения, достойного упоминания, кроме решения вышеупомянутого вопроса, который является ужасным обходным путем, но, похоже, действительно существует больше ничего вокруг.

Мы пытаемся установить связь с устаревшей системой, которая имеет установленную и работающую веб-службу с определенными ограничениями WS-Security, объявленными в ее WSDL. Мы не можем ничего изменить на сервере, мы просто должны сделать так, как он предлагает. У нас также есть сторонняя клиентская реализация, которая на самом деле работает и взаимодействует с сервером, поэтому мы знаем, что связь работает - с использованием ЭТОГО конкретного клиента. Теперь мы хотим сделать свой собственный.

Вышеуказанная политика WS-Security включает шифрование и подпись. Были следующие сценарии того, что делать:

  • написать собственный код для шифрования / дешифрования и подписи / проверки
  • используйте одну из готовых реализаций JAX-WS, чтобы сделать это за нас

Второй вариант, конечно, это то, что мы пытались сделать. Затем мы перейдем к следующему:

  • Metro / WSIT
  • Apache CXF

Все в сети предлагают последний вариант (который я тоже пробовал) - но пока я выбрал первый (тем более, что у нас нет никакой интеграции с Spring, чтобы воспользоваться преимуществами хорошей интеграции CXF с ним)

Поработав с неоднозначной документацией и различными мастерами (NetBeans), мы пришли к решению, которое содержало очень мало пользовательского кода, файл конфигурации с некоторыми хранилищами ключей и обычный сгенерированный код из утилиты wsimport.

Некоторое время прошло с момента выгрузки запросов и ответов XML SOAP, сравнения сбойных, которые мы производим, с успешными, полученными от стороннего клиента. Много боли, без результатов - сообщения различались по-разному, но основная логика и структура были в порядке - тогда - вы не могли фактически сравнить зашифрованные части. Через некоторое время у меня появился клиент, который что-то отправил и получил что-то обратно, но не смог расшифровать ответ.

На самом деле все было расшифровано, но проверка дайджеста подписи не удалась. Стоит отметить, что исходное сообщение XML содержало символ «&», а также несколько новых строк. То есть полезная нагрузка SOAP-сообщения не была синтаксически корректным XML. Так или иначе.

Кажется, что эта проверка дайджеста глубоко укоренилась в стеке Metro / WSIT, и я не мог найти способа реально перехватить и исправить этот дайджест - или фактически содержимое, на основе которого был рассчитан этот дайджест - очевидно, что проблема заключалась в том, что что некоторые специальные символы были переведены или канонизированы либо после, либо до вычисления дайджеста, и мы (точнее, базовая реализация, которую я пытался использовать, чтобы держать руки в чистоте) сделали что-то отличное от того, что делала серверная часть веб-службы.

Даже трубки Metro (хорошее название, но ужасно скудная документация - кажется, что никто не использует Metro / WSIT в наши дни - или, я должен сказать, никто не использует SOAP или SOAP с таким уровнем безопасности? - когда я попробовал Apache CXF, сгенерированные SOAP-сообщения были обманчиво похожи), и их способ перехвата сообщений, похоже, не помог - при попытке получить необработанное содержимое сообщения не было предоставленных методов (Packet.getMessage (). WriteTo ... - и другие варианты) может фактически обойти проверку дайджеста - потому что они ВСЕ пытались прочитать содержимое способом StAX, потоковой передачей и т. д. (вызывая StreamingPayLoadDigester.accept, который неизменно заканчивался ошибкой)

Но надежда умрет последней, и я снова и снова буду пытаться найти какое-то неясное недокументированное волшебство, чтобы заставить мою вещь работать. Хорошо, я собирался назвать это день и усердно копаться в шифровании Java - пока я не нашел вышеупомянутый вопрос, то есть. На самом деле он «эксплуатирует» сообщение журнала, которое печатается из глубины кода Metro (на самом деле из wssx-impl, я думаю) с канонизированным дешифрованным сообщением, прежде чем выдать исключение несоответствия дайджеста. К счастью, это сообщение печатается с использованием java.util.logging, и это может быть перехвачено различными способами - например, отправить его в какую-то синхронизированную очередь для использования моим клиентом. Тьфу. Если у кого-то есть идея получше, пожалуйста, напишите свои мысли.

Спасибо всем.

...