Клиент веб-службы Axis, игнорируя mustUnderstand check - PullRequest
0 голосов
/ 17 января 2020

Я пытаюсь разработать клиент веб-службы для: https://se-face-webservice.redsara.es/facturasspp2?wsdl Безопасность реализована с помощью профиля токена WS-Security 1.0 X.509

Я уже попробовал три подхода :

1) Просто с включенными библиотеками в Java 1.8 и Wsdl2 Java. (JAX-WS?) После большого количества глажения я смог включить сертификат и отправить запрос, но сервер отвечает пользовательской ошибкой «Signature not valid».

2) Axis2, после использования мастера Eclipse 2019-09, я обнаружил, что он слишком сильно портится с моим текущим проектом: много новых jar и новых папок. Слишком много, когда этот веб-сервис включает только около 1% элементов системы.

3) Ось (не рекомендуется) Я использовал мастер Eclipse 2019-09: сначала я обнаружил пару пропавших классов, Похоже, волшебник не добавляет все банки. Я решил это, загрузив wss4j-1.5.8 & xmlse c -1.4.4 (не могу быть уверен, что эти версии работают хорошо с осью 1.4, но ошибки исчезли). После выяснения, как включить сертификат, реализующий обработчик Basi c, я получаю успешный ответ от сервера (я печатаю его на консоль), но при разборе я получаю:

 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}MustUnderstand
 faultSubcode: 
 faultString: Did not understand "MustUnderstand" header(s):{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security 

I В подходе № 1 была похожая или, возможно, такая же ошибка, которую я исправил с помощью первого ответа в SOAPFaultException: «Заголовки MustUnderstand (oasis-200401-wss-wssecurity-secext-1.0.xsd) не поняты» , но Я не знаю, как применить это в сгенерированном коде оси.

Здесь много сообщений в stackoverflow об этой ошибке с осью, но большинство об отключении этой опции в запросе. Кажется, в этом В этом случае я думаю, что сервер работает с MustUnderstand = '1'. В любом случае, мой запрос не включал MustUnderstand в wsse, поэтому я попытался с

_call.setProperty(org.apache.axis.client.Call.CHECK_MUST_UNDERSTAND, Boolean.TRUE)

, но он не сработал. Единственный способ, которым я обнаружил включение Mustunderstand = "1" в свой запрос, - это код в BasicHandler:

WSSecHeader wsSecHeader;
wsSecHeader.setMustUnderstand(true);
...

, но получил ту же ошибку.

В настоящее время я пытаюсь найдите способ как-то обойти эту проверку MustUnderstand, перехватывая и преобразовывая ответ до его анализа. В методе вызова обработчика вы можете добиться этого перехвата:

   public void invoke(MessageContext msgContext) throws AxisFault {

        try {
            //request, include signing with certificate in the header
            ((SOAPPart) msgContext.getRequestMessage().getSOAPPart()).setCurrentMessage(this.createBinarySecurityToken(msgContext),
                    SOAPPart.FORM_SOAPENVELOPE);

            //response
            if(msgContext.getResponseMessage() != null) {
                String transf = msgContext.getResponseMessage().getSOAPPartAsString();
                //
                transf = transf.replace("mustUnderstand=\"1\"" , "");

                msgContext.setResponseMessage(new Message(transf ));
            }

            //Print xml to console
            if(msgContext.getResponseMessage() != null && msgContext.getResponseMessage().getSOAPPart() != null) {
                System.out.println("\n -- RESPONSE -- \n" + msgContext.getResponseMessage().getSOAPPartAsString());
            } else {
                if(msgContext.getRequestMessage() != null && msgContext.getRequestMessage().getSOAPPartAsString() != null) {
                    System.out.println("\n -- REQUEST -- \n" + msgContext.getRequestMessage().getSOAPPartAsString());
                }    
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(-1);
        }
    }

Как вы можете видеть, я наивно думал, что удаление части mustUnderstand из xml будет работать, но я получаю 'SimpleDeserializer, обнаруживший дочерний элемент, что НЕ ожидается, в чем-то, что он пытался десериализовать ».

Я также пытался с чем-то, что нашел, но безуспешно:

                SOAPHeader header = msgContext.getResponseMessage().getSOAPHeader();
                if( header != null )
                {
                    Iterator<?> blocks = header.examineAllHeaderElements();
                    while( blocks.hasNext() )
                    {
                        SOAPHeaderElement block = (SOAPHeaderElement)blocks.next();
                        block.setMustUnderstand(false);
                    }
                }

Должен быть способ игнорировать эта проверка заголовка, потому что тело в ответе показывает ожидаемую информацию, оно там.

Я нашел обходной путь , но он очень грязный. Если я сделаю запрос с подходом № 3, а затем с подходом № 1, неожиданно № 1 теперь работает полностью. Вместо того, чтобы сервер отвечал «Подпись недействительна», я получил правильный ответ, и он анализируется сгенерированными классами. Последующие вызовы только с # 1 работают.

Это не постоянно, когда я пытаюсь на следующий день # 1 вернуться к ошибке, но выполнение обходных / конкатенационных вызовов снова исправляет это. Я уже видел это поведение в течение 3 дней подряд, я не могу понять это, но это может быть временное решение.

Тем временем я также сравню SOAP запросы 1 и 3, чтобы проверить различия в заголовке.

...