consumir - Certificado no confiable usando ksoap2-android
consumir web service soap android studio (4)
Bueno, hay una forma más fácil de hacer esto en lugar de modificar HttpsServiceConnectionSE. Puede instalar un administrador de confianza falso como se describe en http://groups.google.com/group/android-developers/browse_thread/thread/1ac2b851e07269ba/c7275f3b28ad8bbc?lnk=gst&q=certificate y luego llamar a allowAllSSL () antes de hacer cualquier SSL comunicación / llamada a ksoap2. Se registrará un nuevo HostnameVerifier predeterminado y TrustManager. ksoap2, al hacer su comunicación SSL, usará los predeterminados y funciona como un amuleto.
También puede poner más esfuerzo en esto, hacerlo (mucho) más seguro e instalar certificados en un administrador de confianza local de la aplicación, supongo. Estaba en una red segura y no le temo a los hombres en los ataques intermedios, así que acabo de hacer lo primero.
Me pareció necesario usar KeepAliveHttpsTransportSE como este new KeepAliveHttpsTransportSE(host, port, file, timeout);
. Los parámetros entran en un objeto URL, por ejemplo, para acceder a una instalación Jira es algo así como new KeepAliveHttpsTransportSE("host.whatever", 443, "/rpc/soap/jirasoapservice-v2", 1000)
.
A veces es útil si eres nuevo en la tecnología o el servicio web que te gusta usar para jugar con él en un entorno J2SE en lugar de en el emulador o incluso en el dispositivo, pero en la biblioteca J2SE / ME ksoap2 el (KeepAlive) Falta HttpsTransportSE (utilicé ksoap2-j2se-full-2.1.2.jar). Lo que podría hacer es obtener las fuentes para las tres clases HttpsTransportSE, KeepAliveHttpsTransportSE y HttpsServiceConnectionSE del spin-off de Android ksoap2-android y ponerlas en su proyecto J2SE y usarlas. Me funcionó y se convirtió en una mejora de la productividad dar los primeros pasos con un servicio web desconocido y bastante complejo.
Estoy usando ksoap2-android para realizar una llamada al servicio wcf a través de SSL. Puedo hacer que funcione sin SSL, pero ahora quiero hacer la llamada a través de SSL, pero me he encontrado con algunos problemas.
Estoy usando HttpsTransportSE en lugar de HttpTransportSE, pero obtengo el error: javax.net.ssl.SSLException: Certificado de servidor no confiable
¿Cómo puedo arreglar esto?
¿Puedo agregar el certificado del servidor a la Tienda de claves en Android para resolver el problema?
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;
}
Funciona para mí KSOAP + Servicio web WCF con 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 {
}
}
Para complementar la respuesta de Vedran con algún código fuente, lo siento, no puedo comentar.
El trustManager:
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());
}
La llamada a su método:
allowAllSSL();
HttpsTransportSE httpsTransport = new HttpsTransportSE(Server,443, URL, 1000);
Notas:
- Servidor es la URL del servidor.
- 443 es el puerto predeterminado https, aún debe especificar un puerto ya que el constructor espera uno.
- URL la ruta a la operación WS
- 1000 es el tiempo de espera
Que se construye como: [https: // Servidor: 443 / URL]
Sí, probablemente puedas probar esto
Ha habido un error que se ha archivado en Issue Tracker con respecto a esto