15

簡単な説明

安全なリモート SOAP Web サービスに接続するためにJBoss SwitchYardを使用しています。リクエストが送信された後の何らかの理由。リモート Web サービスがそれ以上の通信を停止しています。だから返事が来ない。

質問

ここで問題になる可能性のあるアイデアまたは解決策が必要です。

エラー

原因: java.net.SocketException: https://************.asmx を呼び出す SocketException: サーバーからの予期しないファイルの終わり

説明と注意事項

  • リモート Web サービスは自己署名証明書を使用しています。サーバー証明書をローカルのトラストストアにインポートしました + さらに、リモートサーバーに対して自分自身を識別するための他の証明書を (キーストアに) 持っています。
  • -Djavax.net.debug=all SSL デバッグ ログとWiresharkログのおかげで、クライアントとサーバーの両方が SSL ハンドシェイクに成功し、クライアントが要求を正常に送信したことがわかりました。
  • また、サーバーは IP フィルタリングを使用して直接通信を許可し、私の IP はホワイトリストに登録されています。
  • SoapUIを介して同じ XML リクエストを送信しようとすると、問題なく動作し、応答を受け取ります。SoapUIはキーストアのみを使用することを考慮する必要があります。常にリモート サービスを信頼するように設定されているため、トラストストアは不要または使用されません。
  • 面白い部分が来ます。JBoss SwitchYardとリモート Web サービスの間の「中間者」としてFiddler (無料の Web デバッグ プロキシ)を使用すると (何が起こっているかを確認するため)、突然すべてが機能します。
  • 直接接続とFiddlerをプロキシとして使用する場合の唯一の違いは、実際の接続ではConnection = Keep-Aliveヘッダー パラメータが使用され、Fiddler の場合はProxy-Connection = Keep-Aliveパラメータが使用されることです。他に大きな違いがあるかどうかはわかりません。
  • SoapUIでこれらのヘッダー パラメータを手動で変更しても、正常な応答が返されます。SOAPActionおよびContent-Typeヘッダー パラメータが欠落している場合にのみ接続が失敗しますが、それらはいずれの場合にも存在します (同じです)。
  • Wireshark経由でこの通信を観察すると、リモート サーバーがそれ以上の通信を停止していることだけが分かります ( JBoss Switchyardアプリケーションがリモート Web サービスと直接通信している場合)。
  • リモート ログへのアクセス権がなく、ログを取得することも許可されていません。だから私は盲目的に働いています。
  • いずれの場合も (Fiddler の有無にかかわらず)、会社のプロキシを使用してリモート Web サービスにアクセスしています。他の SwitchYard アプリケーションは正常に動作しているため、このプロキシは問題ではありません。

ツール

  • JBoss Enterprise Application Platform 6.4
  • JBoss SwitchYard 2.0.1.redhat-621159
4

2 に答える 2

1

問題は、無効なヘッダーまたは SOAP リクエストの無効な形式が原因である可能性があります。以下のコードのように試すことができます

1 HeaderHandlerResolverが必要です

 public class HeaderHandlerResolver implements HandlerResolver {

        public List<Handler> getHandlerChain(PortInfo portInfo) {
            List<Handler> handlerChain = new ArrayList<Handler>();

            HeaderHandler hh = new HeaderHandler();

            handlerChain.add(hh);

            return handlerChain;
        }
    }

次に、 HeaderHandlerクラスを追加する必要があります

 public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {

        public boolean handleMessage(SOAPMessageContext smc) {

            Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

            if (outboundProperty.booleanValue()) {

                SOAPMessage message = smc.getMessage();

                try {

                    SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();

                    SOAPHeader header = envelope.getHeader();
                    header.setPrefix("soapenv");
                    header.setAttribute("xmlns:wsa", "http://www.w3.org/2005/08/addressing");

                    SOAPElement security =
                            header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

                    SOAPElement usernameToken =
                            security.addChildElement("UsernameToken", "wsse");
                    usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

                    SOAPElement username =
                            usernameToken.addChildElement("Username", "wsse");
                    username.addTextNode("USERNAME");

                    SOAPElement password =
                            usernameToken.addChildElement("Password", "wsse");
                    password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
                    password.addTextNode("PASSWORD");

                    SOAPElement encode =
                            usernameToken.addChildElement("Nonce", "wsse");
                    encode.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
                    encode.addTextNode(generateNonce());

                    Calendar createdTime = new GregorianCalendar(TimeZone.getTimeZone("IST"));
                    Date todayDate = createdTime.getTime();
                    todayDate.setTime(todayDate.getTime()-20000000);

                    SOAPElement created = usernameToken.addChildElement("Created", "wsu");
                    created.addTextNode(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'").format(todayDate));

                    SOAPElement action = header.addChildElement("Action", "wsa");
                    //YOUR ACTION URL SHOULD BE in BELOW Text Content
                    action.setTextContent("SET HERE YOUR ACTION URL");

                    message.saveChanges();
                    message.writeTo(System.out);
                    System.out.println("");

                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else {
                try {

                    //This handler does nothing with the response from the Web Service so
                    //we just print out the SOAP message.
                    SOAPMessage message = smc.getMessage();
                    message.writeTo(System.out);
                    System.out.println("");
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }


            return outboundProperty;

        }

        public Set getHeaders() {
            return null;
        }

        public boolean handleFault(SOAPMessageContext context) {
            return true;
        }

        public void close(MessageContext context) {
        }

        private static String generateNonce() throws NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException {
            String dateTimeString = Long.toString(new Date().getTime());
            byte[] nonceByte = dateTimeString.getBytes();
            return Base64.encodeBase64String(nonceByte);
        }
    }

最後に、SOAP サービスを呼び出すためのメイン クラス

public class SoapClientClass {

    public static void main(String[] args) {

        ImplService service = new ImplService();
        HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
        service.setHandlerResolver(handlerResolver);

        ResponseClass port = service.getPortClass();

        Response response = null;
        try {
            response = port.getServerMehotd("Params");
        } catch (PolicyException_Exception e) {
            e.printStackTrace();
        } catch (ServiceException_Exception e) {
            e.printStackTrace();
        }

        }
    }
}

また、wsdl ファイル uptodate から生成されたコードとサーバーの場所の URL も正しいことを確認してください。

問題が解決することを願っています

于 2017-05-24T09:31:12.227 に答える