web-dev-qa-db-ja.com

SOAP Webサービスへのメッセージ-HTTP応答コード:URLの403

SOAPファイル内のXMLメッセージをWebサービスに送信して、バイナリ出力を取得してデコードしようとしています。エンドポイントはHTTPSプロトコルを使用するため、TrustManagerの問題を回避するためにコードでPKIXを使用しました。ここに私のコードを見ることができます:

import javax.net.ssl.*;
import Java.io.*;
import Java.net.HttpURLConnection;
import Java.net.URL;
import Java.net.URLConnection;
import Java.security.cert.X509Certificate;

public class Main{
    public static void sendSoapRequest() throws Exception {
        String SOAPUrl = "URL HERE";
        String xmlFile2Send = ".\\src\\request.xml";
        String responseFileName = ".\\src\\response.xml";
        String inputLine;

        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public Java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
            public void checkServerTrusted(X509Certificate[] certs, String authType) { }

        } };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new Java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting Host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) { return true; }
        };
        // Install the all-trusting Host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        // Create the connection with http
        URL url = new URL(SOAPUrl);
        URLConnection connection = url.openConnection();
        HttpURLConnection httpConn = (HttpURLConnection) connection;
        FileInputStream fin = new FileInputStream(xmlFile2Send);
        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        copy(fin, bout);
        fin.close();

        byte[] b = bout.toByteArray();
        StringBuffer buf=new StringBuffer();
        String s=new String(b);

        b=s.getBytes();

        // Set the appropriate HTTP parameters.
        httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
        httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        httpConn.setRequestProperty("SOAPAction", "");
        httpConn.setRequestMethod("POST");
        httpConn.setDoOutput(true);

        OutputStream out = httpConn.getOutputStream();
        out.write(b);
        out.close();

        // Read the response.
        httpConn.connect();
        System.out.println("http connection status :"+ httpConn.getResponseMessage());
        InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
        BufferedReader in = new BufferedReader(isr);

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        FileOutputStream fos=new FileOutputStream(responseFileName);
        copy(httpConn.getInputStream(),fos);
        in.close();
    }

    public static void copy(InputStream in, OutputStream out) throws IOException {

        synchronized (in) {
            synchronized (out) {
                byte[] buffer = new byte[256];
                while (true) {
                    int bytesRead = in.read(buffer);
                    if (bytesRead == -1)
                        break;
                    out.write(buffer, 0, bytesRead);
                }
            }
        }
    }

    public static void main(String args[]) throws Exception {
        sendSoapRequest();
    }
}

これを実行すると、次のエラーコードが表示されます。

スレッド「メイン」の例外Java.io.IOException:サーバーがHTTP応答コードを返しました:URLの403

14
plaidshirt

あなたの実装は大丈夫です、問題は実際には_Content-Type_ヘッダーに関連しています。

値_text/xml; charset=utf-8_は、デフォルトの_Content-Type_ SOAP 1.1であり、おそらく、ご使用のバージョンではありません。 SOAP 1.2は、タイプ_application/soap+xml; charset=utf-8_ なので、コード行を次のコード行に変更すると機能します。

_httpConn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");
_

SoapUIでは、リクエストを呼び出してウィンドウの下部にあるHeadersタブに移動するヘッダーを確認できます。

enter image description here

次に、アプリケーション構成とSoapUI構成の違いを比較できます。

4
bosco

403エラーは、サーバーに送信されるSOAPリクエストヘッダーに関連している可能性があります。すべての有効なホストにより、JavaアプリがURLのSSL証明書を信頼できるようになります。サーバーがユーザー名/パスワード付きのSOAPヘッダーを期待していることを確認してください。このサーバーにアクセスできる場合は、 Webサーバーを介して、リクエストが失敗した場所にログオンします。エラーコードは、Soapヘッダー、特にユーザー名とパスワードを含むSoapヘッダーが欠落していることを示します。

2
tx fun

SOAP=リクエストにSAMLなどのヘッダーにあらゆる種類の認証情報が含まれているのではないかと思います。1つのオプションは、上記のコードで、ファイルを読み取ってサーバーにデータを送信する代わりに、別のファイルにダンプします。そのbyteoutputstreamをダンプします。次に、そのファイルからテキストをコピーし、SOAP UIに入れて実行します。それでうまくいきますか?

1
Gautam

同様の状況では、以前からあり、TrustManagerを試してもうまくいかなかった場合は、サーバーからJVMのキーストア(JVMを使用して応用)。その方法の詳細については、いくつかの投稿に記載されています 。cer証明書をJava keystore?)にインポートする方法

これは、JVMにSSL証明書を受け入れるよう強制する試みであることを認識しています。この機能は、アプリケーションコンテキストで実行する方が適切ですが、特定のアプリケーションサーバーで実行されるWebアプリケーションを構築している限り、実装されたソリューションは受け入れた。

0
lzagkaretos