Je travaille sur une application Android nécessitant une authentification par certificat client (avec les fichiers PKCS 12). Suite à la désapprobation de tout ce qui est Apache.http.*
, nous avons commencé un assez gros travail de refactorisation sur notre couche réseau, et nous avons décidé d’utiliser OkHttp en remplacement, et jusqu’à présent, j’aime beaucoup cela.
Cependant, je n'ai trouvé aucun autre moyen de gérer l'authentification du certificat client sans utiliser SSLSocketFactory
, avec OkHttp ou quoi que ce soit d'autre. Alors, quel serait le meilleur plan d'action dans ce cas particulier? Existe-t-il un autre moyen avec OkHttp de gérer ce type d'authentification?
Apparemment, il existe deux classes SSLSocketFactory
. HttpClient a son propre, qui est déconseillé avec le reste de HttpClient. Cependant, tout le monde utilisera l'édition plus conventionnelle javax.net.ssl
de SSLSocketFactory
, qui n'est pas obsolète (merci $DEITY
).
si vous utilisez https, vous devez utiliser un certificat valide. Pendant votre phase de développement, vous devez faire confiance au certificat. Comment? sslSocketFactory(SSLSocketFactory sslSocketFactory)
est obsolète et remplacé par sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
, vous devez mettre à jour votre fichier Gradle Le morceau de code ci-dessous vous aidera à obtenir un OkHttpClient fiable qui fait confiance tout certificat de ssl.
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager);
Regardez, je trouve une solution et à mes côtés, le travail est bon. Vérifiez comment j'ai intégré ..
OkHttpClient.Builder client = new OkHttpClient.Builder ();
ajoutez ici toutes les propriétés de l'instance client
...
et ajoutez ces lignes de code pour sslSocketFactory:
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(Java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(Java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public Java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new Java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new Java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
client.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
client.hostnameVerifier((hostname, session) -> true);
} catch (Exception e) {
throw new RuntimeException(e);
}