Android WebView tidak memuat URL HTTPS

91
public void onCreate(Bundle savedInstance)
{       
    super.onCreate(savedInstance);
    setContentView(R.layout.show_voucher);
    webView=(WebView)findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setBuiltInZoomControls(true);
    String url ="https://www.paymeon.com/Vouchers/?v=%C80%8D%B1x%D9%CFqh%FA%84%C35%0A%1F%CE&iv=%25%EE%BEi%F4%DAT%E1"
    //webView.loadUrl(url); // Not Working... Showing blank
    webView.loadUrl("http://www.yahoo.com"); // its working    
}

Ketika saya mencoba memuat URL di WebBView, itu hanya menampilkan layar kosong. Jika saya memuat Google.com atau yahoo.com, itu berfungsi dengan baik.

sumit
sumber
1
itu berfungsi, saya periksa sekarang. periksa lagi jika tidak berfungsi setelah itu tambahkan ini dengan kode webView.getSettings (). setUseWideViewPort (true); webView.getSettings (). setLoadWithOverviewMode (true);
ilango j

Jawaban:

156

Silakan kunjungi tautan ini:

Tambahkan metode penggantian ini ke implementasi WebViewClient Anda. Anda harus mengkompilasinya dengan Android SDK 2.2 (API level 8) atau yang lebih baru. Metode ini muncul di SDK publik mulai 2.2 (API level 8) tetapi kami telah mengujinya pada perangkat yang menjalankan 2.1, 1.6 dan 1.5 dan bekerja pada perangkat tersebut juga (jadi jelas perilakunya telah ada selama ini).

 @Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
    handler.proceed(); // Ignore SSL certificate errors
}

ini akan membantumu.

fargath
sumber
3
Entri terakhir dalam diskusi bekerja dengan baik. Terima kasih banyak.
Bill Lahti
55
Peringatan keamanan : Perhatikan bahwa melakukan hal itu sepenuhnya mengalahkan tujuan memiliki SSL di tempat pertama.
sebelum
8
Tolong jangan lakukan ini. Ini tidak aman dan tidak diizinkan di Play Store.
Antimony
34
Google sekarang mengirimkan email kepada siapa pun yang menerapkan solusi di atas:Your app(s) listed at the end of this email have an unsafe implementation of the WebViewClient.onReceivedSslError handler. Specifically, the implementation ignores all SSL certificate validation errors, making your app vulnerable to man-in-the-middle attacks. Apps with vulnerabilities that expose users to risk of compromise may be considered Dangerous Products in violation of the Content Policy and section 4.4 of the Developer Distribution Agreement.
Gustavo
3
Ada yang tahu cara mengatasi peringatan Keamanan Google, jika ya tolong beri tahu saya karena saya juga menghadapi masalah ini.
Pratik Tank
49

Per jawaban yang benar menurut fargth, berikut adalah contoh kode kecil yang mungkin bisa membantu.

Pertama, buat kelas yang memperluas WebViewClient dan yang disetel untuk mengabaikan kesalahan SSL:

// SSL Error Tolerant Web View Client
private class SSLTolerentWebViewClient extends WebViewClient {

            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed(); // Ignore SSL certificate errors
            }

}

Kemudian dengan objek tampilan web Anda (dimulai dalam metode OnCreate ()), setel klien tampilan webnya menjadi turunan dari kelas timpa:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );
robnick
sumber
2
ini memberikan peringatan keamanan google: implementasi tidak aman dari handler WebViewClient.onReceivedSslError. apakah Anda tahu bagaimana mengatasi ini?
Pratik Tank
2
Google Menandai Aplikasi Sebagai Unsaif di playstore bagaimana bisa melakukannya tanpa ssl?
Ajay Pandya
Jangan gunakan metode Super- super.onReceivedSslError (view, handler, error);
Atul Bhardwaj
41

Untuk menangani validasi sertifikat SSL dengan benar dan menghindari penolakan aplikasi dari Google sesuai dengan Kebijakan Keamanan baru, Ubah kode Anda untuk memanggil SslErrorHandler.proceed () setiap kali sertifikat yang diberikan oleh server memenuhi harapan Anda, dan panggil SslErrorHandler.cancel () jika tidak.

Misalnya, saya menambahkan dialog peringatan agar pengguna mengonfirmasi dan sepertinya Google tidak lagi menampilkan peringatan.

    @Override
    public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    String message = "SSL Certificate error.";
        switch (error.getPrimaryError()) {
            case SslError.SSL_UNTRUSTED:
                message = "The certificate authority is not trusted.";
                break;
            case SslError.SSL_EXPIRED:
                message = "The certificate has expired.";
                break;
            case SslError.SSL_IDMISMATCH:
                message = "The certificate Hostname mismatch.";
                break;
            case SslError.SSL_NOTYETVALID:
                message = "The certificate is not yet valid.";
                break;
        }
        message += " Do you want to continue anyway?";

        builder.setTitle("SSL Certificate Error");
        builder.setMessage(message);
    builder.setPositiveButton("continue", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.proceed();
        }
    });
    builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.cancel();
        }
    });
    final AlertDialog dialog = builder.create();
    dialog.show();
}

Setelah perubahan ini tidak akan muncul peringatan.

Anant Shah
sumber
apa yang akan terjadi jika saya menghapus blok onReceivedSslError dari implementasi?
Vivek Sinha
1
@VivekSinha akan memanggil handler.cancel (); secara default.
Anant Shah
1
tapi Google tetap menolak aplikasi saya dengan alasan yang sama. Mengapa?
Vivek Sinha
@VivekSinha menemukan solusi apa pun terkait peluncuran aplikasi di play store?
Kesha
2
Saya menerapkan callback onReceivedSslError seperti yang disarankan. Aplikasi berhasil diterbitkan setelah itu.
Vivek Sinha
11

Hapus kode di bawah ini itu akan berfungsi

 super.onReceivedSslError(view, handler, error);
King of Masses
sumber
Bagus, itu berhasil untuk saya. Bisakah Anda menjelaskan cara kerjanya?
Arth Tilva
3
@ArthTilva dari google docs: "perilaku default adalah membatalkan pemuatan". Dengan memanggil super, Anda memanggil perilaku default tersebut sebelum dapat menjangkau seluruh metode. developer.android.com/reference/android/webkit/…
Josh Laird
11

override onReceivedSslError dan hapus

super.onReceivedSslError (tampilan, penangan, kesalahan)

Dan untuk mengatasi keamanan Google:

setDomStorageEnabled (true);

Kode lengkapnya adalah:

webView.enableJavaScript();
webView.getSettings().setDomStorageEnabled(true); // Add this
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebViewClient(new WebViewClient(){
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            // DO NOT CALL SUPER METHOD
            super.onReceivedSslError(view, handler, error);
        }
    });
FarshidABZ
sumber
Terima kasih banyak. Menghapus super.onReceivedSslError (view, handler, error) berhasil untuk saya.
Däñish Shärmà
7

Salin dan tempel baris kode sobat, ini akan berhasil, percayalah :) Saya berpikir, Anda mendapatkan kesalahan ssl. Jika Anda menggunakan metode override onReceivedSslError dan menghapus metode super itu super. Cukup tulis handler.proceed (), kesalahan akan teratasi.

    webView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {

            activity.setTitle("Loading...");
            activity.setProgress(progress * 100);

            if (progress == 100)
                activity.setTitle(getResources().getString(R.string.app_name));
        }
    });

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Log.d("Failure Url :" , failingUrl);
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
            Log.d("Ssl Error:",handler.toString() + "error:" +  error);
            handler.proceed();
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setLoadWithOverviewMode(true);
    webView.getSettings().setUseWideViewPort(true);
    webView.getSettings().setDomStorageEnabled(true);
    webView.loadUrl(Constant.VIRTUALPOS_URL + "token=" + Preference.getInstance(getContext()).getToken() + "&dealer=" + Preference.getInstance(getContext()).getDealerCode());
ozanurkan
sumber
Terima kasih. Hubungi handler.proceed () untuk onReceivedSslErrormenyelamatkan hari saya
Tam Huynh
2
Jika Anda melakukan ini (sekarang Juli 2019) google play akan menolak aplikasi Anda.
Alp Altunel
İ memiliki terlalu banyak aplikasi di google play, tidak ada aplikasi yang masih ditolak.
ozanurkan
1
akan menolak Januari 2020 dengan kata-kata
John Ruban Singh
6

Untuk menangani url SSL metode onReceivedSslError () dari kelas WebViewClient, Ini adalah contohnya:

 webview.setWebViewClient(new WebViewClient() {
              ...
              ...
              ...

            @Override
            public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
                String message = "SSL Certificate error.";
                switch (error.getPrimaryError()) {
                    case SslError.SSL_UNTRUSTED:
                        message = "The certificate authority is not trusted.";
                        break;
                    case SslError.SSL_EXPIRED:
                        message = "The certificate has expired.";
                        break;
                    case SslError.SSL_IDMISMATCH:
                        message = "The certificate Hostname mismatch.";
                        break;
                    case SslError.SSL_NOTYETVALID:
                        message = "The certificate is not yet valid.";
                        break;
                }
                message += "\"SSL Certificate Error\" Do you want to continue anyway?.. YES";

                handler.proceed();
            }

        });

Anda dapat memeriksa contoh lengkap saya di sini: https://github.com/Jorgesys/Android-WebView-Logging

masukkan deskripsi gambar di sini

Jorgesys
sumber
6

Untuk mengatasi keamanan Google, lakukan ini:

Garis ke atas:

import android.webkit.SslErrorHandler;
import android.net.http.SslError;

Kode:

class SSLTolerentWebViewClient extends WebViewClient {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        if (error.toString() == "piglet")
            handler.cancel();
        else
            handler.proceed(); // Ignore SSL certificate errors
    }
}
Ronen
sumber
2
Saya baru mengenal Android. Di mana saya harus meletakkan ini? :)
Gediminas
5

Saya mengikuti jawaban di atas tetapi tetap saja sepertinya tidak berfungsi untuk saya di bawah kode melakukan trik bagi saya ketika mengintegrasikan gateway pembayaran yang biasanya merupakan permintaan https:

public class MainActivity extends Activity {

    WebView webView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webView1);
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        webView.setWebViewClient(new MyWebViewClient());
        String postData = "amount=1000&firstname=mtetno&[email protected]&phone=2145635784&productinfo=android&surl=success.php"
                + "&furl=failure.php&lastname=qwerty&curl=dsdsd.com&address1=dsdsds&address2=dfdfd&city=dsdsds&state=dfdfdfd&"
                + "country=fdfdf&zipcode=123456&udf1=dsdsds&udf2=fsdfdsf&udf3=jhghjg&udf4=fdfd&udf5=fdfdf&pg=dfdf";
        webView.postUrl(
                "http://host/payment.php",
                EncodingUtils.getBytes(postData, "BASE64"));

    }

    private class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            webView.loadUrl(url);
            return true;
        }

        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                SslError error) {
            handler.proceed();
        }
    }
}

Kode di atas adalah melakukan permintaan posting di webview dan mengarahkan ke gateway pembayaran.

Pengaturan settings.setDomStorageEnabled(true);melakukan trik bagi saya Semoga ini bisa membantu.

KOTIOS
sumber
2
Solusi ini SEPENUHNYA menonaktifkan validasi sertifikat, membuat Anda terbuka untuk serangan man-in-the-middle. Ini adalah sesuatu yang tidak boleh Anda lakukan, TERUTAMA untuk gateway pembayaran.
Dirbaio
Bagi saya awalnya tampilan web tidak memuat konten, tetapi hanya gambar latar belakang halaman. Setelah saya menambahkannya webview.getSettings.setDomStorageEnabled(true);secara ajaib bekerja. Mungkin halaman web menggunakan semacam API HTML 5, jadi mengaktifkan DomStorage berhasil untuk saya.
Ishant Sagar
handler.proceed () melewati SSL
John Ruban Singh
apa itu Encodingutil.getbyte
Akash kumar
2

Pendekatan yang direkomendasikan akan

1. Jangan sebut super metode (Hapus panggilan super dari metode yang diganti)

2. Google merekomendasikan untuk memanggil SslErrorHandler.cancel () metode jika ada kesalahan

3. Jangan Prompt dialog untuk mengekspos kesalahan SSL

Apa solusi terbaik ?? Hapus metode penggantian ini

@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error) {

}
John Ruban Singh
sumber
Apakah Anda meminta solusi atau menyarankan solusi?
Dharman
Saya menyarankan pendekatan ini
John Ruban Singh
@JohnRubanSingh Hai John, Saya telah memuat file JS dari aset dan setelah file dimuat dengan onPageFinished, saya memanggil fungsi di dalam JS. Jadi, menimpa onReceivedSslError () diperlukan karena saya menggunakan webview.setWebViewClient (new ....)?
Shivam Sharma
Kode ini menolak APK saya. Bahkan sejak 9 bulan kode ini tidak menyebabkan penolakan tetapi tiba-tiba menghadapi penolakan r8 sekarang. switch (error.getPrimaryError ()) {case SslError.SSL_UNTRUSTED: handler.proceed (); istirahat; case SslError.SSL_EXPIRED: case SslError.SSL_IDMISMATCH: case SslError.SSL_NOTYETVALID: case SslError.SSL_DATE_INVALID: case SslError.SSL_INVALID: default: handler.cancel (); istirahat; }
Shivam Sharma
@JohnRubanSingh tolong bantu saya. Kita bisa bergabung saat kendur.
Shivam Sharma
0

Menyetel dua properti itu cukup untuk membuatnya berfungsi untuk saya, dan tidak mengekspos masalah keamanan:

 WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setDomStorageEnabled(true);
GreuM
sumber
0

Gunakan baris ini webview.getSettings (). SetDomStorageEnabled (true) dalam kode java Anda

WebView webView = (WebView) findViewById(R.id.webview);    
webView.getSettings().setDomStorageEnabled(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl(yourUrl);
Abdul Basit Resi
sumber
0

Jika Anda ingin menggunakan APK di luar Google Play Store, misalnya, solusi pribadi seperti berikut mungkin akan berfungsi:

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        /*...*/
        handler.proceed();
    }

Jika Anda ingin menambahkan lapisan keamanan opsional tambahan, Anda dapat mencoba menggunakan penyematan sertifikat . IMHO ini tidak perlu untuk penggunaan pribadi atau internal yang sulit.

Jika Anda berencana untuk memublikasikan aplikasi di Google Play Store, Anda harus menghindari @Override onReceivedSslError (...) {...}. Terutama memanfaatkan handler.proceed (). Google akan menemukan cuplikan kode ini dan akan menolak aplikasi Anda dengan pasti karena solusi dengan handler.proceed () akan menyembunyikan semua jenis mekanisme keamanan bawaan .

Dan hanya karena fakta bahwa browser tidak mengeluh tentang koneksi https Anda, bukan berarti sertifikat SSL itu sendiri dipercaya sama sekali!

Dalam kasus saya, rantai sertifikat SSL rusak. Anda dapat dengan cepat menguji masalah tersebut dengan SSL Checker atau lebih menengah dengan SSLLabs . Tapi tolong jangan tanya saya bagaimana ini bisa terjadi. Saya sama sekali tidak tahu.

Bagaimanapun, setelah menginstal ulang sertifikat SSL, semua kesalahan terkait " sertifikat SSL tidak tepercaya di WebView apa pun " akhirnya menghilang. Saya juga menghapus @Override untuk onReceivedSslError (...) dan menyingkirkan handler.proceed () , dan é voila aplikasi saya tidak ditolak oleh Google Play Store (lagi).

Manuel
sumber