Kode di bawah ini berfungsi untuk mempercayai sertifikat yang ditandatangani sendiri. Anda harus menggunakan TrustSelfSignedStrategy saat membuat klien Anda:
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
sslsf).build();
HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
System.out.println(response.getStatusLine());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} finally {
response.close();
}
Saya tidak menyertakan dengan SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
sengaja: Intinya adalah untuk mengizinkan pengujian dengan sertifikat yang ditandatangani sendiri sehingga Anda tidak harus memperoleh sertifikat yang sesuai dari otoritas sertifikasi. Anda dapat dengan mudah membuat sertifikat yang ditandatangani sendiri dengan nama host yang benar, jadi lakukan itu alih-alih menambahkan SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
bendera.
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
SSLContextBuilder
ditemukan oleh Idea.Jika Anda menggunakan prosedur PoolingHttpClientConnectionManager di atas tidak berfungsi, SSLContext kustom akan diabaikan. Anda harus meneruskan socketFactoryRegistry di contructor saat membuat PoolingHttpClientConnectionManager.
sumber
HttpClients.custom().setConnectionManager(cm).build()
danHttpClients.custom().setSSLSocketFactory(connectionFactory).build()
akan berfungsi, jadi Anda tidak perlu membuatPoolingHttpClientConnectionManager
Sebagai tambahan untuk jawaban @mavroprovato, jika Anda ingin mempercayai semua sertifikat alih-alih hanya ditandatangani sendiri, Anda akan melakukannya (dengan gaya kode Anda)
atau (salin-tempel langsung dari kode saya sendiri):
Dan jika Anda juga ingin melewati verifikasi nama host, Anda perlu menyetelnya
demikian juga. (ALLOW_ALL_HOSTNAME_VERIFIER tidak digunakan lagi).
Peringatan wajib: Anda tidak seharusnya melakukan ini, menerima semua sertifikat adalah hal yang buruk. Namun ada beberapa kasus penggunaan yang jarang terjadi di mana Anda ingin melakukan ini.
Sebagai catatan untuk kode yang diberikan sebelumnya, Anda akan ingin menutup respons meskipun httpclient.execute () melontarkan pengecualian
Kode di atas telah diuji menggunakan
Dan bagi yang tertarik, inilah set pengujian lengkap saya:
(proyek uji kerja di github )
sumber
Satu tambahan kecil untuk jawaban vasekt:
Solusi yang disediakan dengan SocketFactoryRegistry berfungsi saat menggunakan PoolingHttpClientConnectionManager.
Namun, koneksi melalui http biasa tidak berfungsi lagi. Anda harus menambahkan PlainConnectionSocketFactory untuk protokol http tambahan untuk membuatnya berfungsi kembali:
sumber
http
protokol digunakanPlainConnectionSocketFactory
secara default. Saya hanya mendaftarhttps
danhttpclient
masih bisa mendapatkan URL HTTP biasa. jadi menurut saya langkah ini tidak perlu.PoolingHttpClientConnectionManager
Setelah mencoba berbagai opsi, konfigurasi berikut berfungsi untuk http dan https
Saya menggunakan http-client 4.3.3 -
compile 'org.apache.httpcomponents:httpclient:4.3.3'
sumber
Kode kerja yang lebih sederhana dan lebih pendek:
sumber
Berikut adalah penyulingan yang berfungsi dari teknik di atas, setara dengan "curl --insecure":
sumber
Saat menggunakan http client 4.5 saya harus menggunakan javasx.net.ssl.HostnameVerifier untuk mengizinkan nama host (untuk tujuan pengujian). Inilah yang akhirnya saya lakukan:
sumber
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);
denganSSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);
. Ini menghindari kelas anonim dan membuat kode sedikit lebih mudah dibaca.Di atas
PoolingHttpClientConnectionManager
bersama denganRegistry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build();
Jika Anda ingin httpclient asynchronous menggunakanPoolingNHttpClientConnectionManager
kode harus mirip dengan berikutsumber
Jika Anda menggunakan
HttpClient 4.5.x
, kode Anda bisa serupa dengan berikut ini:sumber
sumber
Percayai Semua Sertifikat di Klien HTTP Apache
sumber
(Saya akan menambahkan komentar langsung ke jawaban vasekt tetapi saya tidak memiliki cukup poin reputasi (tidak yakin logikanya di sana)
Bagaimanapun ... yang ingin saya katakan adalah bahwa meskipun Anda tidak secara eksplisit membuat / meminta PoolingConnection, tidak berarti Anda tidak mendapatkannya.
Saya menjadi gila mencoba mencari tahu mengapa solusi asli tidak berhasil untuk saya, tetapi saya mengabaikan jawaban vasekt karena "tidak berlaku untuk kasus saya" - salah!
Saya sedang menatap jejak tumpukan saya ketika rendah dan lihatlah saya melihat Sambungan Pooling di tengahnya. Bang - Aku lelah dengan penambahan dan kesuksesannya !! (demo kami besok dan saya semakin putus asa) :-)
sumber
Anda dapat menggunakan potongan kode berikut untuk mendapatkan contoh HttpClient tanpa pemeriksaan sertifikasi ssl.
sumber
Sedikit tweak untuk menjawab dari @divbyzero di atas untuk memperbaiki peringatan keamanan sonar
sumber
Awalnya, saya dapat menonaktifkan untuk localhost menggunakan strategi kepercayaan, kemudian saya menambahkan NoopHostnameVerifier. Sekarang ini akan berfungsi untuk localhost dan nama mesin apa pun
sumber