Frage

Ich bin mit ksoap2-android einen Anruf zu WCF-Dienst über SSL zu machen. Ich kann es Arbeit ohne SSL, aber jetzt möchte ich den Anruf über SSL machen, aber ich habe in zu einigen Problemen führen.

Ich bin mit der HttpsTransportSE statt HttpTransportSE, aber ich bin immer die Fehlermeldung: javax.net.ssl.SSLException: Nicht vertrauenswürdige Server-Zertifikat

Wie kann ich dieses Problem beheben?

Kann ich das Server-Zertifikat auf den Schlüsselspeicher in Android fügen Sie das Problem zu lösen?

private static final String SOAP_ACTION = "http://example.com/Service/GetInformation";
private static final String METHOD_NAME = "GetInformation";
private static final String NAMESPACE = "http://example.com";    
private static final String URL = "dev.example.com/Service.svc";

public static Result GetInformation()
{
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

    PropertyInfo property = new PropertyInfo();
    property.name = "request";

    Request request =
        new Request("12", "13", "Ben");

    userInformationProperty.setValue(request);
    userInformationProperty.setType(request.getClass());
    request.addProperty(property);

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;
    envelope.setOutputSoapObject(request);
    envelope.addMapping(NAMESPACE, "Request",new Request().getClass());

    HttpsTransportSE transport = new HttpsTransportSE(URL, 443, "", 1000);

    //HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
    transport.debug = true;

    try
    {
        transport.call(SOAP_ACTION, envelope);          
        return Result.FromSoapResponse((SoapObject)envelope.getResponse());
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch (XmlPullParserException e)
    {
        e.printStackTrace();
    }

    return null;
}
War es hilfreich?

Lösung

Nun, es ist ein einfacher Weg, dies zu tun, anstatt modifizierende HttpsServiceConnectionSE. Sie können einen gefälschten Trust-Manager installieren, wie in http://groups.google.com/group/android-developers/browse_thread/thread/1ac2b851e07269ba/c7275f3b28ad8bbc?lnk=gst&q=certificate und rufen Sie dann allowAllSSL (), bevor Sie auf eine beliebige SSL-Kommunikation / Anruf tun ksoap2 . Es wird eine neue Standard-HostnameVerifier und Trustmanager registrieren. ksoap2, wenn seine SSL-Kommunikation zu tun, werden die Standardeinstellungen verwenden, und es funktioniert wie ein Charme.

Sie können auch etwas mehr Mühe in diese setzen, machen es (viel) sicherer und Installation von Zertifikaten in einer Anwendung lokalen Trust-Manager, denke ich. Ich war in einem sicheren Netzwerk und keine Angst vor Man-in-the-Middle-Angriffe so habe ich nur die erste.

Ich fand es notwendig, KeepAliveHttpsTransportSE wie diese new KeepAliveHttpsTransportSE(host, port, file, timeout); zu verwenden. Die Parameter gehen in ein URL-Objekt, so z.B. der Zugriff auf eine er ist so etwas wie new KeepAliveHttpsTransportSE("host.whatever", 443, "/rpc/soap/jirasoapservice-v2", 1000) Jira Installation.

Manchmal ist es praktisch, wenn Sie in die Technik neu sind oder die Web-Service, den Sie verwenden möchten mit ihm in einer J2SE-Umgebung zu spielen, um statt in dem Emulator oder sogar auf dem Gerät, sondern in der J2SE / ME ksoap2 Bibliothek der (Keep-Alive) HttpsTransportSE Material fehlt (I verwendet ksoap2-j2se-full-2.1.2.jar). Was Sie tun können, die Quellen für die drei Klassen zu erhalten, ist HttpsTransportSE, KeepAliveHttpsTransportSE und HttpsServiceConnectionSE aus der Android Spin-off ksoap2-android und nimm sie auf dem J2SE Projekt und nutzt sie. Er arbeitete für mich, und es wurde eine Verbesserung der Produktivität, die ersten Schritte rechts mit einem unbekannten und recht komplexen Web-Service zu erhalten.

Andere Tipps

Um die Antwort von Vedran mit einigen Quellcode ergänzen, sorry kann ich nicht kommentieren.

Die Trust:

private static TrustManager[] trustManagers;

public static class _FakeX509TrustManager implements
        javax.net.ssl.X509TrustManager {
    private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};

    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
    }

    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
    }

    public boolean isClientTrusted(X509Certificate[] chain) {
        return (true);
    }

    public boolean isServerTrusted(X509Certificate[] chain) {
        return (true);
    }

    public X509Certificate[] getAcceptedIssuers() {
        return (_AcceptedIssuers);
    }
}

public static void allowAllSSL() {

    javax.net.ssl.HttpsURLConnection
            .setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

    javax.net.ssl.SSLContext context = null;

    if (trustManagers == null) {
        trustManagers = new javax.net.ssl.TrustManager[] { new _FakeX509TrustManager() };
    }

    try {
        context = javax.net.ssl.SSLContext.getInstance("TLS");
        context.init(null, trustManagers, new SecureRandom());
    } catch (NoSuchAlgorithmException e) {
        Log.e("allowAllSSL", e.toString());
    } catch (KeyManagementException e) {
        Log.e("allowAllSSL", e.toString());
    }
    javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(context
            .getSocketFactory());
}

Der Aufruf an Ihrer Methode:

allowAllSSL();
HttpsTransportSE httpsTransport = new HttpsTransportSE(Server,443, URL, 1000);

Weitere Informationen:

  1. Server ist die Server-URL.
  2. 443 ist die Standard-HTTPS-Port, können Sie immer noch einen Port angeben müssen, da der Konstruktor man erwartet.
  3. URL der Pfad zum WS Betrieb
  4. 1000 es das Timeout

, die als aufgebaut ist: [Https: // Server: 443 / URL]

Funktioniert bei mir KSOAP + Web Service WCF mit Eclipse

private static SoapObject getBody(final SoapSerializationEnvelope soapEnvelope) throws Exception {
        if (soapEnvelope.bodyIn == null) {
            throw new Exception("soapEnvelope.bodyIn=null");
        }
        else if (soapEnvelope.bodyIn.getClass() == SoapFault.class) {
            throw new ExceptionLogic((SoapFault) soapEnvelope.bodyIn));
        }
        else {
            return (SoapObject) soapEnvelope.bodyIn;
        }

    }

private static SoapSerializationEnvelope sendRequete(final SoapObject soapReq, final String classMappingName,
            final Class<?> classMapping, final int timeOutSpecial) {



        final SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        soapEnvelope.implicitTypes = true;
        soapEnvelope.dotNet = true;

        if (classMappingName != null) {
            soapEnvelope.addMapping(NAMESPACE, classMappingName, classMapping);
        }

        soapEnvelope.setOutputSoapObject(soapReq);

        try {

            final HttpTransportSE httpTransport = new HttpTransportSE(Constante.urlWebService, timeOutSpecial);
            httpTransport.debug = BuildConfig.DEBUG;

            // Prod
            if (Constante.urlWebService.startsWith("https://")) {
                final List<HeaderProperty> headerList = new ArrayList<HeaderProperty>();
                headerList.add(new HeaderProperty("Authorization", "Basic "
                        + org.kobjects.base64.Base64.encode((Constante.CERTIFICAT_LOGIN + ":" + Constante.CERTIFICAT_MDP).getBytes())));

                FakeX509TrustManager.allowAllSSL();
                httpTransport.call(NAMESPACE + "/" + soapReq.getName(), soapEnvelope, headerList);
            }
            // Test
            else {
                httpTransport.call(NAMESPACE + "/" + soapReq.getName(), soapEnvelope);
            }

            return soapEnvelope;
        }
        catch (final Exception e) {
            throw new Exception("Erreur : " + e.getMessage(), e);
        }

    }



    private static class FakeX509TrustManager implements X509TrustManager {
        private static TrustManager[] trustManagers;
        private final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return _AcceptedIssuers;
        }

        public static void allowAllSSL() {
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {

                @Override
                public boolean verify(final String hostname, final SSLSession session) {
                    return true;
                }
            });
            SSLContext context = null;
            if (trustManagers == null) {
                trustManagers = new TrustManager[] { new FakeX509TrustManager() };
            }
            try {
                context = SSLContext.getInstance("TLS");
                context.init(null, trustManagers, new SecureRandom());
            }
            catch (final NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            catch (final KeyManagementException e) {
                e.printStackTrace();
            }
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
        }

        @Override
        public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {

        }
    }

Ja wahrscheinlich können Sie dies ausprobieren

Https-Verbindung Android

Es hat einen Fehler gegeben, die auf Issue Tracker zu diesem

eingereicht wurde

http://code.google.com/p/android / Themen / detail? id = 2388

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top