Сообщение SOAP для webservice - код ответа HTTP: 403 для URL

Я пытаюсь отправить сообщение SOAP в файл XML в веб-службу, а затем захватить двоичный вывод и декодировать его. Конечная точка использует протокол 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();
    }
}

Я получаю следующий код ошибки, когда выполняю это.

Исключение в потоке "main" java.io.IOException: сервер возвратил HTTP код ответа: 403 для URL

Ответы

Ответ 1

Ваша реализация в порядке, проблема связана с вашим заголовком 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 можно проверить заголовки, вызывающие запрос, и перейти на вкладку "Заголовки" в нижней части окна:

введите описание изображения здесь

Затем вы можете сравнить различия между конфигурациями приложений и SoapUI.

Ответ 2

Ошибка 403 может быть связана с заголовками запросов на мыло, отправляемыми на сервер. Все действительные хосты позволят вашему Java-приложению доверять SSL-сертификату для URL-адреса. Проверьте, ожидает ли ваш сервер заголовка мыла с именем пользователя/паролем. Если у вас есть доступ к этому серверу, вы можете просмотреть журналы веб-сервера, где ваш запрос терпит неудачу. Код ошибки указывает на отсутствие заголовка мыла, в частности заголовков мыла, с именем пользователя и паролем.

Ответ 3

Интересно, содержит ли ваш запрос SOAP какие-либо данные проверки подлинности в таких заголовках, как SAML. Один из вариантов - в приведенном выше коде, где вы читаете файл и отправляете данные на сервер, вместо того, чтобы отправлять его на сервер, вы выгружаете его в другой файл. Дамп, что byteoutputstream. Затем скопируйте текст из этого файла и поместите его в пользовательский интерфейс SOAP и попробуйте запустить его. Это работает?

Ответ 4

В аналогичной ситуации мы были раньше, и пока попытка TrustManager не работает должным образом, нам удалось преодолеть эту проблему, установив сертификат с сервера на хранилище JVM (JVM, используемое для запуска выражение). Более подробную информацию о том, как это сделать, можно найти в нескольких сообщениях, например Как импортировать сертификат .cer в хранилище java?

Я знаю, что это попытка заставить JVM принимать SSL-сертификаты, и эта функциональность будет лучше жить в контексте приложения, но пока мы создаем веб-приложение, которое запускается на определенных серверах приложений, реализовано решение было принятым.