http://madurangasblogs.blogspot.in/2013/08/avoiding-javaxnetsslsslpeerunverifiedex.html
Avec l'aimable autorisation de Maduranga
Lorsque vous développez une application qui utilise https, votre serveur de test ne dispose pas d'un certificat SSL valide. Ou parfois le site web utilise un certificat auto-signé ou le site web utilise un certificat SSL gratuit. Donc si vous essayez de vous connecter au serveur en utilisant Apache HttpClient
vous obtiendrez une exception indiquant que le "peer not authenticated". Bien que ce ne soit pas une bonne pratique de faire confiance à tous les certificats dans un logiciel de production, vous pouvez avoir à le faire en fonction de la situation. Cette solution résout l'exception causée par "peer not authenticated".
Mais avant de passer à la solution, je dois vous avertir que ce n'est pas une bonne idée pour une application de production. Cela violerait l'objectif de l'utilisation d'un certificat de sécurité. Donc, à moins que vous n'ayez une bonne raison ou que vous soyez sûr que cela ne posera aucun problème, n'utilisez pas cette solution.
Normalement, vous créez un HttpClient
comme ça.
HttpClient httpclient = new DefaultHttpClient();
Mais vous devez modifier la façon dont vous créez le HttpClient.
Tout d'abord, vous devez créer une classe étendant org.apache.http.conn.ssl.SSLSocketFactory
.
import org.apache.http.conn.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
Créez ensuite une méthode comme celle-ci.
public HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
Ensuite, vous pouvez créer le HttpClient
.
HttpClient httpclient = getNewHttpClient();
Si vous essayez d'envoyer une demande de courrier à une page de connexion, le reste du code sera le suivant.
private URI url = new URI("url of the action of the form");
HttpPost httppost = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("username", "user"));
nameValuePairs.add(new BasicNameValuePair("password", "password"));
try {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Vous récupérez la page html dans l'InputStream. Ensuite, vous pouvez faire ce que vous voulez avec la page html renvoyée.
Mais ici, vous allez rencontrer un problème. Si vous voulez gérer une session en utilisant des cookies, vous ne pourrez pas le faire avec cette méthode. Si vous voulez obtenir les cookies, vous devrez le faire via un navigateur. Vous serez alors le seul à recevoir des cookies.
0 votes
Puis-je obtenir un exemple de mise en œuvre de la même chose ?
0 votes
Ce fil de discussion peut aider, mais je ne peux pas dire si cela fonctionne avec la dernière API : groups.google.com/group/Android-developers/browse_thread/thread/