WSIT не понимает заголовок безопасности SOAP после запроса с настраиваемым заголовком безопасности
Я пишу клиент веб-сервисов Java с использованием библиотек Metro/WSIT, а веб-сервисы, которые мне нужны, - это сервисы WCF. (У меня практически нет контроля над сервисной стороной и WSDL.)
Веб-службы защищены как с помощью протокола транспортного уровня (SSL), так и с помощью федеративной модели безопасности со службой маркеров безопасности (WS-Trust/WS-Security). Я легко реализовал клиенты в.NET с помощью Windows Identity Foundation, сначала выдав токен безопасности, а затем с помощью метода ( CreateChannelWithIssuedToken) отправляя запросы другим веб-службам.
Мне трудно подражать этому поведению в Java, хотя, используя Metro/WSIT. Насколько я понимаю, из-за недостатка информации WS-Policy в WSDL WSIT не разрешит обработку безопасности для связи со службой. Я сделал это вручную при создании запросов, манипулируя заголовками запросов SOAP перед его отправкой, и теперь я получаю сообщения, идентичные тем, которые я получал бы на стороне клиента.NET.
Теперь моя проблема в том, что я получаю следующую ошибку:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
at com.sun.xml.ws.protocol.soap.MUTube.createMUSOAPFaultException(MUTube.java:148)
at com.sun.xml.ws.protocol.soap.ClientMUTube.processResponse(ClientMUTube.java:96)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:972)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:910)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:873)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:775)
at com.sun.xml.ws.client.Stub.process(Stub.java:429)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:168)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:102)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:151)
потому что у ответа SOAP есть заголовок Security в заголовке:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2012-05-14T21:20:08.782Z</u:Created>
<u:Expires>2012-05-14T21:25:08.782Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
...
Учитывая, что я не могу изменить WSDL, есть ли способ, которым я могу вручную заставить Metro/WSIT включить обработку безопасности для ответа, чтобы это исключение не выдавалось? Я не собираюсь использовать заголовки безопасности, а полезная нагрузка ответа соответствует ожидаемой. Я понимаю, что вижу правильное поведение, если клиент не понимает заголовок с mustunderstand="1", но я ищу способ подавить это исключение.
Я читал другие вопросы, такие как этот, которые кажутся близкими к тому, что я хочу, но я пока не нашел ответа. Любые советы / решения / и т. Д. с благодарностью!
1 ответ
Я нашел обходной путь (подходящий на данный момент), включающий нестандартную "трубу", вставленную в конвейер обработки Metro.
Я создал пользовательский класс обработки труб, который расширяет com.sun.xml.ws.api.pipe.helper.AbstractFilterTubeImpl
и переопределяет processResponse( Packet packet )
, ищем заголовки с именем "Безопасность" и вызываем packet.getMessage().getHeaders().understood( int )
для индекса в списке заголовков заголовка безопасности, который я нашел. Это препятствует тому, чтобы обработка вниз по трубе пыталась понять заголовки безопасности (поскольку проблема в том, что это не так).
После этого я создал трубный завод com.sun.xml.ws.assembler.TubeFactory
) для моей кастомной трубки.
Затем я скопировал содержимое webservices-rt.jar/META-INF/metro-default.xml в META-INF/metro.xml в моем проекте и добавил <tube-factory>
элемент для моего фабричного класса; под <client-side>
Я положил его чуть выше фабрики транспортных труб, и под <endpoint-side>
Я поместил его в верхнюю часть списка, над фабрикой транспортных труб.
Надеюсь, это поможет любому с подобной проблемой. Возможность добавлять пользовательскую обработку в конвейер Metro кажется невероятно мощной, но и опасной; YMMV.