Мой вопрос связан с этим а>
У меня были недели головной боли, чтобы попытаться бороться с этим, но, похоже, не существует решения, достойного упоминания, кроме решения вышеуказанного вопроса, который является ужасным обходным путем, но на самом деле кажется, что ничего другого вокруг не существует. .
Мы пытаемся связаться с устаревшей системой, в которой есть установленная и работающая веб-служба с определенными ограничениями WS-Security, объявленными в ее WSDL. Мы не можем ничего изменить на сервере, мы просто должны делать то, что он предлагает. У нас также есть сторонняя реализация клиента, которая на самом деле работает и взаимодействует с сервером, поэтому мы знаем, что связь работает - с использованием ЭТОГО конкретного клиента. Теперь мы хотим сделать свой собственный.
Приведенная выше политика WS-Security включает шифрование и подпись. Были следующие сценарии того, что делать:
- написать собственный код для шифрования/дешифрования и подписи/проверки
- используйте одну из готовых реализаций JAX-WS, чтобы сделать это за нас
Второй вариант, конечно, то, что мы пытались сделать. Затем мы переходим к следующему:
- Метро/WSIT
- Апач 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, и его можно перехватить различными способами, например. отправить его в какую-то синхронизированную очередь для использования моим клиентом. Фу. Если у кого-то есть идея получше, пишите свои мысли.
Спасибо вам всем.