Poste HTTP seguro en Android
Tengo una clase de ayudante bastante básica que estoy usando para hacer todas mis cosas de Http Get / Post. Estoy usando HttpGet, HttpPost y HttpClient de la biblioteca org.apache.http. Todas mis cosas funcionan bien a través de HTTP, pero tan pronto como traté de consumir un servicio que funciona a través de HTTPS, obtengo una ClientProtocolException al ejecutar la solicitud. El único mensaje en la excepción es "El servidor no respondió con una respuesta HTTP válida".
Para probar, envié la misma carga exacta desde un navegador usando un simple formulario html y Fiddler2 usando RequestBuilder. He enviado cargas útiles no válidas y vacías e incluso envió todo lo anterior con y sin encabezados para ver si había algo funky sobre la forma en que los objetos estaban construyendo la solicitud.
- Evitar el bloqueo del dispositivo en android mientras mi actividad está en ejecución Y el dispositivo está conectado al cargador
- Cómo restringir los intentos de Android o agregar seguridad
- Leyendo ActivityManager-logs en un dispositivo de Jelly Bean?
- La consola del programador de Google Play rechazó mi actualización de aplicación
- ¿Qué tan seguras son las API de GeoLocation en dispositivos móviles?
Todo lo que he usado en las pruebas me da una respuesta válida de 200 status HTTP. El servicio sólo me da una estructura que describe el error si le doy algo más que lo que espera.
¿Hay algo especial que necesito agregar al objeto HttpPost o HttpClient para decirle que use HTTPS? ¿Tengo que decirle explícitamente que utilice un puerto diferente?
EDITAR:
De hecho, registró la fábrica de socket equivocada para la comunicación https. Aquí está el método actualizado que utilizo para crear mi objeto HttpClient con la fábrica de socket correcta en caso de que alguien busque este tipo de problema en el futuro:
private HttpClient createHttpClient() { HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); return new DefaultHttpClient(conMgr, params); }
- Android 4.3: ¿Cómo puedo comprobar si el usuario tiene activado el bloqueo?
- Oauth 2.0: identificación del cliente y secreto del cliente expuestos, ¿es un problema de seguridad?
- ¿Qué protege las contraseñas de AccountManager de Android de ser leídas por otras aplicaciones?
- ¿Cómo puedo importar un certificado de la CA en Android 4.4.2 en el emulador?
- Herramienta de análisis de código fuente estático de código abierto (orientada a la seguridad) para Java
- Evitar el "cliente falso" para la aplicación ios
- ¿Qué tan seguro acceder a mi aplicación de Android con facebook-id?
- Hacer que el teclado Android resista a los ataques de KeyLogger
No estoy seguro de por qué no puede manejar HTTPS. Escribí una clase de ayudante para mis propias aplicaciones y soy capaz de GET / POST a HTTPS sin ningún problema. Voy a publicar el código aquí y tal vez usted puede ver si hay diferencias entre mi código y el suyo.
import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.params.ClientPNames; import org.apache.http.client.params.CookiePolicy; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import android.util.Log; public class HttpRequest{ DefaultHttpClient httpClient; HttpContext localContext; private String ret; HttpResponse response = null; HttpPost httpPost = null; HttpGet httpGet = null; public HttpRequest(){ HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); httpClient = new DefaultHttpClient(myParams); localContext = new BasicHttpContext(); } public void clearCookies() { httpClient.getCookieStore().clear(); } public void abort() { try { if (httpClient != null) { System.out.println("Abort."); httpPost.abort(); } } catch (Exception e) { System.out.println("Your App Name Here" + e); } } public String sendPost(String url, String data) { return sendPost(url, data, null); } public String sendJSONPost(String url, JSONObject data) { return sendPost(url, data.toString(), "application/json"); } public String sendPost(String url, String data, String contentType) { ret = null; httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); httpPost = new HttpPost(url); response = null; StringEntity tmp = null; Log.d("Your App Name Here", "Setting httpPost headers"); httpPost.setHeader("User-Agent", "SET YOUR USER AGENT STRING HERE"); httpPost.setHeader("Accept", "text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"); if (contentType != null) { httpPost.setHeader("Content-Type", contentType); } else { httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); } try { tmp = new StringEntity(data,"UTF-8"); } catch (UnsupportedEncodingException e) { Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e); } httpPost.setEntity(tmp); Log.d("Your App Name Here", url + "?" + data); try { response = httpClient.execute(httpPost,localContext); if (response != null) { ret = EntityUtils.toString(response.getEntity()); } } catch (Exception e) { Log.e("Your App Name Here", "HttpUtils: " + e); } Log.d("Your App Name Here", "Returning value:" + ret); return ret; } public String sendGet(String url) { httpGet = new HttpGet(url); try { response = httpClient.execute(httpGet); } catch (Exception e) { Log.e("Your App Name Here", e.getMessage()); } //int status = response.getStatusLine().getStatusCode(); // we assume that the response body contains the error message try { ret = EntityUtils.toString(response.getEntity()); } catch (IOException e) { Log.e("Your App Name Here", e.getMessage()); } return ret; } public InputStream getHttpStream(String urlString) throws IOException { InputStream in = null; int response = -1; URL url = new URL(urlString); URLConnection conn = url.openConnection(); if (!(conn instanceof HttpURLConnection)) throw new IOException("Not an HTTP connection"); try{ HttpURLConnection httpConn = (HttpURLConnection) conn; httpConn.setAllowUserInteraction(false); httpConn.setInstanceFollowRedirects(true); httpConn.setRequestMethod("GET"); httpConn.connect(); response = httpConn.getResponseCode(); if (response == HttpURLConnection.HTTP_OK) { in = httpConn.getInputStream(); } } catch (Exception e) { throw new IOException("Error connecting"); } // end try-catch return in; } }
Como algunos de los métodos son obsoletos, should'nt que sea así?
private DefaultHttpClient createHttpClient() { HttpParams params = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(params, 10000); HttpConnectionParams.setSoTimeout(params, 10000); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory())); schReg.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); ClientConnectionManager conMgr = new PoolingClientConnectionManager(schReg); return new DefaultHttpClient(conMgr, params); }
¿Debo cambiar algo más, como HttpVersion?
- Si llamo getMeasuredWidth () o getWidth () para el diseño en onResume devuelven 0
- NPE en Facebook SDK 4.10: Intenta invocar el método de interfaz 'java.lang.Object com.facebook.inject.Lazy.get ()' en una referencia de objeto nulo