Подключитесь к безопасному веб-сервису в Android с помощью KSoap2 - PullRequest
0 голосов
/ 21 февраля 2012

Я пытаюсь подключиться к безопасному веб-сервису в приложении для Android с помощью KSoap2, но у меня возникли некоторые трудности. Я посмотрел несколько учебных пособий и других вопросов / ответов по StackOverflow, но пока ничего не помогло.

У меня есть идентичный веб-сервис на незащищенном сервисе, и я могу подключиться к нему просто отлично. Я не уверен, нужно ли мне устанавливать SSL-соединение вручную или KSoap2 должен все это обрабатывать при использовании защищенного сервиса?

Я пытаюсь использовать найденное решение здесь , но я получаю следующую ошибку:

java.io.IOException: Relative path:  
https://XXXXXXXX.net/FPSecureService/ClientService.svc

При использовании SoapUI я могу без проблем подключиться к защищенному веб-сервису - мне нужно установить имя пользователя и пароль, а также тип WSS-пароля на «PasswordText», и тогда он будет работать нормально. Я пытался заставить мой Java-код имитировать сгенерированный SoapUI код запроса, насколько смог. Все, что я добавляю в заголовок, - это попытка сделать его идентичным сгенерированному SoapUI запросу, но это не сработало.

Вот мой код вызова веб-службы:

public void secureWebServiceCall () {

    // secure service
    String mUrl = "https://XXXXXXXX.net/FPSecureService/ClientService.svc"; 

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 

    String clientID = "XXXXXXX";

    PropertyInfo pi = new PropertyInfo();
    pi.setName("nationalID"); 
    pi.setValue(clientID); 
    pi.setType(clientID.getClass()); 
    request.addProperty(pi);

    // build Envelope
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
    envelope.dotNet = true;

    // Apdd mapping and marshalling
    envelope.addMapping(NAMESPACE, "GetClientByNationalID", new ClientID().getClass());
    Marshal floatMarshal = new MarshalFloat();
    floatMarshal.register(envelope); 


    // Construct soap envelope headers
    Element[] header = new Element[1];
    header[0] = new Element().createElement("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Security");
    header[0].setAttribute(null, "mustUnderstand","1");
    Element usernametoken = new Element().createElement("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "UsernameToken");
    usernametoken.setAttribute("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "UsernameToken-1");
    header[0].addChild(Node.ELEMENT,usernametoken);
    Element username = new Element().createElement(null, "n0:Username");
    username.addChild(Node.TEXT, "XXXXXXXX");
    usernametoken.addChild(Node.ELEMENT, username);
    Element pass = new Element().createElement(null, "n0:Password");
    pass.setAttribute(null, "Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
    pass.addChild(Node.TEXT, "XXXXXXX");
    usernametoken.addChild(Node.ELEMENT, pass);
    Element nonce = new Element().createElement(null, "n0:Nonce"); 
    nonce.setAttribute(null, "EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
    nonce.addChild(Node.TEXT, "eic5EdyTomcBLocwyph5Mw==");
    usernametoken.addChild(Node.ELEMENT, nonce);
    Element created = new Element().createElement(null, "n0:Created");
    created.addChild(Node.TEXT, "2012-02-08T09:47:55.225Z");
    usernametoken.addChild(Node.ELEMENT, created); 

    envelope.headerOut = header; 

    // Set Output Soap Object as Request
    envelope.setOutputSoapObject(request); 
    HttpTransportSE t = new HttpTransportSE(mUrl);
    AndroidInsecureKeepAliveHttpsTransportSE androidTransport = 
new AndroidInsecureKeepAliveHttpsTransportSE("XXXXXXXX.net", 80, mUrl, 50000);


    ClientID client = new ClientID(); 
    t.debug = true; 

    try { 
        Log.i("webServiceCall", "Trying call to web service");
        // t.call(SOAP_ACTION, envelope);
        androidTransport.call(SOAP_ACTION, envelope); 
        SoapObject response = (SoapObject) envelope.getResponse();
        TextView tv = (TextView) findViewById(R.id.textView1); 
        tv.setText(response.getPropertyAsString(3)); 

        Log.i("success", response.getPropertyAsString(0)); 
        Log.i("success", response.getPropertyAsString(1));
        Log.i("success", response.getPropertyAsString(2));
        Log.i("success", response.getPropertyAsString(3));
        Log.i("success", response.getPropertyAsString(4)); 
        System.out.println("Request: "  + t.requestDump); 
        System.out.println("Response: " + t.responseDump);

    } catch (Exception e) {
        Log.e("webServiceCall", "Error calling webservice.");
        e.printStackTrace(); 
        System.out.println("Request: "  + t.requestDump); 
        System.out.println("Response: " + t.responseDump);
    }

}

У кого-нибудь есть идеи? Я чувствовал, что, возможно, наконец-то что-то получу с AndroidInsecureHttpsServiceConnection и всеми этими SSL-вещами, но это не работает. Я не могу не чувствовать, что где-то допустил простую ошибку, но я не знаю, что это такое. Эта ошибка "Относительный путь" заставляет меня чувствовать, что это что-то очень простое сделать с параметрами, которые я передаю, но я новичок в этом и не уверен, какие параметры я должен указывать и как я должен их указывать ,

Любая помощь будет высоко ценится.

Ответы [ 2 ]

0 голосов
/ 25 марта 2014

Этот сайт: http://obtao.com/blog/2013/09/how-to-use-wsse-in-android-app/ объясняет, как генерировать одноразовый номер, кодировать его и включать в заголовок. Если вы копируете одноразовый номер из soapui, он должен потерпеть неудачу на серверной части, так как весь смысл одноразового номера состоит в том, чтобы предотвратить такое воспроизведение. Вы должны сгенерировать свой собственный, как показано в примере, на который ссылаются.

0 голосов
/ 21 февраля 2012

Используйте KeepAliveHttpsTransportSE из проекта ksaop2-android .Он прекрасно работает для меня.

И подтвердите, что URL-адрес прекрасно отображает службу в браузере на устройстве, чтобы проверить доступность прокси и т. Д.

Из вашего кодаскорее всего, это вызывает проблемы:

 HttpTransportSE t = new HttpTransportSE(mUrl);
    AndroidInsecureKeepAliveHttpsTransportSE androidTransport = 
new AndroidInsecureKeepAliveHttpsTransportSE("XXXXXXXX.net", 80, mUrl, 50000);

Не используйте один транспорт внутри другого таким образом.Вместо этого используйте конструктор или AndroidInsecureKeepAliveHttpsTransportSE, что угодно.Конструкторы выполняют некоторую инициализацию, и если вы будете использовать их повторно, она, скорее всего, начнет работать.

...