Android WebView ไม่โหลด URL HTTPS


93
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    
}

เมื่อฉันพยายามโหลด URL ใน WebBView จะแสดงเฉพาะหน้าจอว่างเปล่า ถ้าฉันโหลด Google.com หรือ yahoo.com ก็ใช้ได้ดี


1
มันใช้งานได้ฉันตรวจสอบแล้ว ตรวจสอบอีกครั้งหากไม่ทำงานหลังจากนั้นเพิ่มสิ่งนี้ด้วยรหัสของคุณ webView.getSettings (). setUseWideViewPort (true); webView.getSettings (). setLoadWithOverviewMode (จริง);
ilango j

คำตอบ:


157

กรุณาเยี่ยมชมลิงค์นี้:

เพิ่มวิธีการลบล้างนี้ในการใช้งาน WebViewClient ของคุณ คุณจะต้องคอมไพล์ด้วย Android SDK 2.2 (API ระดับ 8) หรือใหม่กว่า วิธีนี้ปรากฏใน SDK สาธารณะ ณ 2.2 (API ระดับ 8) แต่เราได้ทดสอบกับอุปกรณ์ที่ใช้ 2.1, 1.6 และ 1.5 และใช้ได้กับอุปกรณ์เหล่านั้นด้วย (เห็นได้ชัดว่าพฤติกรรมนี้มีมาตลอด)

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

สิ่งนี้จะช่วยคุณได้


3
รายการสุดท้ายในการอภิปรายทำงานได้ดี ขอบคุณมาก ๆ.
Bill Lahti

57
คำเตือนด้านความปลอดภัย : โปรดทราบว่าการทำเช่นนี้เป็นการเอาชนะวัตถุประสงค์ของการมี SSL ตั้งแต่แรก
เมื่อ

8
กรุณาอย่าทำเช่นนี้ ไม่ปลอดภัยและไม่ได้รับอนุญาตใน Play Store
Antimony

35
ขณะนี้ Google กำลังส่งอีเมลถึงใครก็ตามที่ใช้วิธีแก้ปัญหาข้างต้น: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
มีใครทราบวิธีแก้คำเตือนความปลอดภัยของ Google ถ้าใช่โปรดแจ้งให้เราทราบเพราะฉันประสบปัญหานี้เช่นกัน
Pratik Tank

49

ต่อคำตอบที่ถูกต้องโดย fargth ต่อไปนี้เป็นตัวอย่างโค้ดขนาดเล็กที่อาจช่วยได้

ขั้นแรกสร้างคลาสที่ขยาย WebViewClient และตั้งค่าให้ละเว้นข้อผิดพลาด 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
            }

}

จากนั้นด้วยออบเจ็กต์มุมมองเว็บของคุณ (เริ่มต้นในเมธอด OnCreate ()) ให้ตั้งค่าไคลเอ็นต์มุมมองเว็บเป็นอินสแตนซ์ของคลาสแทนที่:

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

2
สิ่งนี้ทำให้คำเตือนความปลอดภัยของ Google: การใช้งานตัวจัดการ WebViewClient.onReceivedSslError อย่างไม่ปลอดภัย คุณรู้วิธีแก้ปัญหานี้หรือไม่?
Pratik Tank

2
Google ทำเครื่องหมายแอปเป็น Unsaif บน playstore จะทำอย่างไรโดยไม่ใช้ ssl
Ajay Pandya

อย่าใช้ Super method- super.onReceivedSslError (view, handler, error);
Atul Bhardwaj

43

ในการจัดการการตรวจสอบใบรับรอง SSL อย่างเหมาะสมและหลีกเลี่ยงการปฏิเสธแอปพลิเคชันจาก Google ตามนโยบายความปลอดภัยใหม่ให้เปลี่ยนรหัสของคุณเพื่อเรียกใช้ SslErrorHandler.proceed () เมื่อใดก็ตามที่ใบรับรองที่เซิร์ฟเวอร์แสดงนั้นตรงกับความคาดหวังของคุณและเรียกใช้ SslErrorHandler.cancel () เป็นอย่างอื่น

ตัวอย่างเช่นฉันเพิ่มกล่องโต้ตอบการแจ้งเตือนเพื่อให้ผู้ใช้ยืนยันและดูเหมือนว่า Google จะไม่แสดงคำเตือนอีกต่อไป

    @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();
}

หลังจากการเปลี่ยนแปลงนี้จะไม่แสดงคำเตือน


จะเกิดอะไรขึ้นถ้าฉันลบบล็อก onReceivedSslError ออกจากการใช้งาน
Vivek Sinha

1
@VivekSinha มันจะเรียก handler.cancel (); โดยค่าเริ่มต้น.
Anant Shah

1
แต่ Google ยังคงปฏิเสธแอปของฉันโดยบอกเหตุผลเดียวกัน ทำไม?
Vivek Sinha

@VivekSinha พบวิธีแก้ปัญหาเกี่ยวกับการเปิดตัวแอพใน play store หรือไม่?
Kesha

2
ฉันใช้การโทรกลับ onReceivedSslError ตามที่แนะนำ เผยแพร่แอปเรียบร้อยแล้วในภายหลัง
Vivek Sinha

11

ลบโค้ดด้านล่างจะใช้งานได้

 super.onReceivedSslError(view, handler, error);

เยี่ยมมากมันได้ผลสำหรับฉัน คุณช่วยอธิบายวิธีการทำงานได้ไหม
Arth Tilva

3
@ArthTilva จาก Google เอกสาร: "การทำงานเริ่มต้นคือการยกเลิกการโหลด" การโทรหา super หมายความว่าคุณกำลังเรียกใช้พฤติกรรมเริ่มต้นนั้นก่อนที่จะสามารถเข้าถึงวิธีการอื่น ๆ developer.android.com/reference/android/webkit/…
Josh Laird

11

แทนที่ onReceivedSslError และลบ

super.onReceivedSslError (มุมมองตัวจัดการข้อผิดพลาด)

และเพื่อแก้ปัญหาความปลอดภัยของ Google:

setDomStorageEnabled (จริง);

รหัสเต็มคือ:

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);
        }
    });

ขอบคุณผู้ชายมาก การลบ super.onReceivedSslError (มุมมองตัวจัดการข้อผิดพลาด) ใช้ได้ผลสำหรับฉัน
DäñishShärmà

7

คัดลอกและวางสายรหัสของคุณมันจะใช้งานได้เชื่อฉัน :) ฉันคิดว่าคุณได้รับข้อผิดพลาด ssl หากคุณใช้วิธีการแทนที่ onReceivedSslError และลบ super it's super method เพียงเขียน handler.proceed () ข้อผิดพลาดจะแก้ไขได้

    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());

ขอบคุณ. โทรหา handler.proceed () ในonReceivedSslErrorบันทึกวันของฉัน
Tam Huynh

2
หากคุณทำสิ่งนี้ (ตอนนี้ในเดือนกรกฎาคม 2019) Google Play จะปฏิเสธใบสมัครของคุณ
Alp Altunel

İมีแอปพลิเคชันมากเกินไปใน Google Play ไม่มีแอปใดที่ยังถูกปฏิเสธ
ozanurkan

1
จะปฏิเสธคำพูดในเดือนมกราคม 2020
John Ruban Singh

6

ในการจัดการกับ SSL urls เมธอด onReceivedSslError ()จากคลาส WebViewClient นี่คือตัวอย่าง:

 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();
            }

        });

คุณสามารถตรวจสอบตัวอย่างทั้งหมดของฉันได้ที่นี่: https://github.com/Jorgesys/Android-WebView-Logging

ป้อนคำอธิบายภาพที่นี่


6

ในการแก้ปัญหาความปลอดภัยของ Google ให้ดำเนินการดังนี้:

เส้นไปด้านบน:

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

รหัส:

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
    }
}

2
ฉันเพิ่งเคยใช้ Android ฉันควรวางสิ่งนี้ไว้ที่ไหน? :)
Gediminas

5

ฉันทำตามคำตอบด้านบน แต่ดูเหมือนว่าจะไม่ได้ผลสำหรับฉันด้านล่างโค้ดนี้เป็นเคล็ดลับสำหรับฉันเมื่อรวมเกตเวย์การชำระเงินซึ่งโดยปกติจะเป็นคำขอ 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=mttee@gmail.com&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();
        }
    }
}

โค้ดด้านบนกำลังส่งคำขอโพสต์ใน webview และเปลี่ยนเส้นทางไปยังเกตเวย์การชำระเงิน

การตั้งค่าsettings.setDomStorageEnabled(true);เป็นเคล็ดลับสำหรับฉันหวังว่านี่จะช่วยได้


2
โซลูชันนี้จะปิดใช้งานการตรวจสอบใบรับรองโดยสมบูรณ์โดยปล่อยให้คุณเปิดไว้สำหรับการโจมตีแบบคนกลาง นี่คือสิ่งที่คุณไม่ควรทำโดยเฉพาะอย่างยิ่งสำหรับเกตเวย์การชำระเงิน
Dirbaio

สำหรับฉันในตอนแรกการดูเว็บไม่ได้โหลดเนื้อหา แต่เป็นเพียงภาพพื้นหลังของหน้า หลังจากที่ฉันเพิ่งเพิ่มwebview.getSettings.setDomStorageEnabled(true);มันทำงานได้อย่างน่าอัศจรรย์ บางทีหน้าเว็บอาจใช้ HTML 5 API บางประเภทดังนั้นการเปิดใช้ DomStorage จึงใช้ได้กับฉัน
Ishant Sagar

handler.proceed () ข้าม SSL
John Ruban Singh

Encodingutil.getbyte คืออะไร
Akash kumar

2

แนวทางที่แนะนำจะเป็น

1. อย่าเรียก super method (ลบ super call ออกจาก overridden method)

2. Google แนะนำให้เรียกใช้เมธอด SslErrorHandler.cancel ()หากมีข้อผิดพลาดเกิดขึ้น

3. อย่าให้กล่องโต้ตอบแสดงข้อผิดพลาด SSL

ทางออกที่ดีที่สุดคืออะไร ?? ลบวิธีการลบล้างนี้

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

}

คุณกำลังขอวิธีแก้ปัญหาหรือแนะนำ?
Dharman

ฉันแนะนำแนวทางนี้
John Ruban Singh

@JohnRubanSingh สวัสดีจอห์นฉันโหลดไฟล์ JS จากแอสเซทและเมื่อไฟล์โหลดด้วย onPageFinished ฉันเรียกใช้ฟังก์ชันภายใน JS ดังนั้นการแทนที่ onReceivedSslError () จึงจำเป็นเนื่องจากฉันใช้ webview.setWebViewClient (ใหม่ .... )?
Shivam Sharma

รหัสนี้ปฏิเสธ APK ของฉันตั้งแต่ 9 เดือนรหัสนี้ไม่ได้ทำให้เกิดการปฏิเสธ แต่จู่ๆก็ถูกปฏิเสธ r8 ในขณะนี้ สวิตช์ (error.getPrimaryError ()) {case SslError.SSL_UNTRUSTED: handler.proceed (); หยุดพัก; กรณี SslError.SSL_EXPIRED: case SslError.SSL_IDMISMATCH: case SslError.SSL_NOTYETVALID: case SslError.SSL_DATE_INVALID: case SslError.SSL_INVALID: default: handler.cancel (); หยุดพัก; }
Shivam Sharma

@JohnRubanSingh ได้โปรดช่วยฉันด้วย เราสามารถเข้าร่วมได้
Shivam Sharma

0

การตั้งค่าคุณสมบัติสองอย่างก็เพียงพอที่จะทำให้ใช้งานได้สำหรับฉันและไม่เปิดเผยปัญหาด้านความปลอดภัย:

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

0

ใช้บรรทัดนี้webview.getSettings (). setDomStorageEnabled (true)ในโค้ด java ของคุณ

WebView webView = (WebView) findViewById(R.id.webview);    
webView.getSettings().setDomStorageEnabled(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.loadUrl(yourUrl);

0

ในกรณีที่คุณต้องการใช้ APK นอก Google Play Store เช่นโซลูชันส่วนตัวดังต่อไปนี้อาจใช้งานได้:

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

ในกรณีที่คุณต้องการเพิ่มเลเยอร์ความปลอดภัยเพิ่มเติมคุณสามารถลองใช้การตรึงใบรับรองการตรึงใบรับรองIMHO สิ่งนี้ไม่จำเป็นสำหรับการใช้งานส่วนตัวหรือภายในที่ยากลำบาก

หากคุณวางแผนที่จะเผยแพร่แอปบน Google Play Store คุณควรหลีกเลี่ยง @Override onReceivedSslError (... ) {... } โดยเฉพาะอย่างยิ่งการใช้ handler.proceed () Google จะค้นหาข้อมูลโค้ดนี้และจะปฏิเสธแอปของคุณเพื่อตรวจสอบว่าตั้งแต่แก้ปัญหาด้วย handler.proceed () จะปราบปรามทุกชนิดในตัวกลไกการรักษาความปลอดภัย

และเพียงเพราะความจริงที่ว่าเบราว์เซอร์ไม่บ่นเกี่ยวกับการเชื่อมต่อ https ของคุณมันไม่ได้หมายความว่าใบรับรอง SSL นั้นเชื่อถือได้เลย!

ในกรณีของฉันห่วงโซ่ใบรับรอง SSLเสีย คุณสามารถทดสอบปัญหาดังกล่าวได้อย่างรวดเร็วด้วยSSL Checkerหรือมากกว่าระดับกลางด้วยSSLLabs SSLLabsแต่โปรดอย่าถามฉันว่ามันเกิดขึ้นได้อย่างไร ฉันไม่มีเงื่อนงำอย่างแน่นอน

อย่างไรก็ตามหลังจากติดตั้งใบรับรอง SSL ใหม่แล้วข้อผิดพลาดทั้งหมดเกี่ยวกับ " ใบรับรอง SSL ที่ไม่น่าเชื่อถือใน WebView ก็ตาม " ก็หายไปในที่สุด ฉันยังลบ @Override สำหรับ onReceivedSslError (... ) และกำจัด handler.proceed ()และé voila แอปของฉันไม่ได้ถูกปฏิเสธโดย Google Play Store (อีกครั้ง)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.