Android WebViewがHTTPS URLをロードしない


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    
}

WebBViewにURLをロードしようとすると、空白の画面しか表示されません。Google.comまたはyahoo.comをロードすると、問題なく動作します。


1
それは私が今チェックした動作しています。それでも機能しない場合は、コードwebView.getSettings()。setUseWideViewPort(true);でこれを追加して、もう一度確認してください。webView.getSettings()。setLoadWithOverviewMode(true);
ilango j 2011

回答:


154

このリンクにアクセスしてください:

このオーバーライドメソッドをWebViewClient実装に追加します。Android SDK 2.2(APIレベル8)以降でコンパイルする必要があります。このメソッドは2.2(APIレベル8)の時点でパブリックSDKに表示されますが、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

54
セキュリティ警告:これを行うと、そもそもSSLを使用する目的が完全に無効になることに注意してください。
ereOn 2014年

8
これを行わないでください。安全ではないため、Playストアでは許可されていません。
アンチモン2015年

33
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.
グスタボ

3
誰でもgoogleのセキュリティ警告を解決する方法を知っています。もしそうなら、私もこの問題に直面しているので私に知らせてください。
Pratikタンク2016

48

正解ごとに、以下は役立つかもしれない小さなコードサンプルです。

まず、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
            }

}

次に、Webビューオブジェクト(OnCreate()メソッドで開始)を使用して、そのWebビュークライアントをオーバーライドクラスのインスタンスに設定します。

 mWebView.setWebViewClient(
                new SSLTolerentWebViewClient()
        );

2
これにより、Googleのセキュリティ警告が表示されます。WebViewClient.onReceivedSslErrorハンドラの安全でない実装です。これを解決する方法を知っていますか?
Pratikタンク

2
GoogleはPlaystoreでアプリをUnsaifとしてマークしましたが、sslなしでそれを行うにはどうすればよいですか?
Ajay Pandya 2016

Superメソッドを使用しないでください-super.onReceivedSslError(view、handler、error);
Atul Bhardwaj

40

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ストアでのアプリの起動に関する解決策を見つけましたか?
ケシャ

2
提案されているように、onReceivedSslErrorコールバックを実装しました。その後、アプリは正常に公開されました。
Vivek Sinha 2017年

11

動作する以下のコードを削除します

 super.onReceivedSslError(view, handler, error);

すばらしいです。それがどのように機能したか説明していただけますか?
Arth Tilva 2016

3
Googleドキュメントの@ArthTilva:「デフォルトの動作はロードをキャンセルすることです」。superを呼び出すと、メソッドの残りの部分に到達する前に、デフォルトの動作が呼び出されます。 developer.android.com/reference/android/webkit/...
ジョシュ・レアード

11

onReceivedSslErrorをオーバーライドして削除

super.onReceivedSslError(ビュー、ハンドラー、エラー)

そして、Googleのセキュリティを解決するには:

setDomStorageEnabled(true);

完全なコードは次のとおりです。

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(view、handler、error)を削除するとうまくいきました。
デニッシュシャーマ

7

あなたのコード行をコピーして貼り付けてください、それは私を信頼して機能します:)私は考えています、あなたはsslエラーを受け取ります。オーバーライドonReceivedSslErrorメソッドを使用し、superのスーパーメソッドを削除する場合。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());

ありがとう。onReceivedSslErrorsave my day でhandler.proceed()を呼び出す
Tam Huynh

2
これを行う場合(現在2019年7月)、Google Playはアプリケーションを拒否します。
Alp Altunel

google Google Playにアプリケーションが多すぎますが、拒否されるアプリケーションはありません。
ozanurkan

1
は、2020年1月のオンワードを拒否します
John Ruban Singh

6

SSL URLを処理するには、WebViewClientクラスのメソッド onReceivedSslError()を使用します。次に例を示します。

 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でpostリクエストを実行し、支払いゲートウェイにリダイレクトしています。

設定settings.setDomStorageEnabled(true);は私のためにトリックを行いましたこれが役立つことを願っています。


2
このソリューションは完全に証明書の検証を無効にするので、中間者攻撃に対応できます。これは、特に決済ゲートウェイでは絶対にすべきではないことです。
Dirbaio 2017

私にとって、最初はウェブビューはコンテンツをロードしていませんでしたが、ページの背景画像だけをロードしていました。追加webview.getSettings.setDomStorageEnabled(true);した後、それは魔法のように機能しました。Webページで何らかのHTML 5 APIを使用している可能性があるため、DomStorageを有効にするとうまくいきました。
Ishant Sagar 2017

SSLをバイパスするhandler.proceed()
John Ruban Singh

Encodingutil.getbyteとは
Akash kumar

2

推奨されるアプローチは

1. スーパーに電話しないでくださいメソッドを(オーバーライドされたメソッドからスーパー呼び出しを削除する)

2. GoogleはSslErrorHandler.cancel()を呼び出すことをお勧めします、エラーが発生した場合にメソッド

3. ダイアログ表示してSSLエラーを公開しない

最高の解決策は何ですか? このオーバーライドメソッドを削除

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

}

解決策を求めていますか、それとも提案していますか?
ダーマン、

私はこのアプローチを提案しています
John Ruban Singh

@JohnRubanSinghこんにちは、私はJSファイルをアセットからロードしました。onPageFinishedでファイルをロードしたら、JS内の関数を呼び出しています。したがって、webview.setWebViewClient(new ....)を使用しているため、onReceivedSslError()のオーバーライドが必要ですか?
Shivam Sharma

このコードは私のAPKを拒否します。9か月以来、このコードは拒否を引き起こしていませんが、突然拒否r8に直面しています。スイッチ(error.getPrimaryError()){ケースSslError.SSL_UNTRUSTED:handler.proceed(); ブレーク; case 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

これらの2つのプロパティを設定するだけで十分に機能し、セキュリティの問題は発生しません。

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

0

Javaコードでこの行webview.getSettings()。setDomStorageEnabled(true)を使用します

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

0

Google Playストアの外でAPKを使用する場合、たとえば、プライベートでは、次のようなソリューションがおそらく機能します。

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

オプションのセキュリティ層をさらに追加したい場合は、証明書のピン留めを利用してみてください。私見これは私的または内部的な使用が難しい場合には必要ありません。

アプリをGoogle Playストアで公開する場合は、@ Override onReceivedSslError(...){...}回避する必要があります特にhandler.proceed()を利用しています。Googleはこのコードスニペットを検出し、handler.proceed()を使用したソリューションがあらゆる種類の組み込みのセキュリティメカニズムを抑制するため、アプリを確実に拒否します。

また、ブラウザがhttps接続について文句を言わないという事実のために、SSL証明書自体がまったく信頼されているという意味ではありません!

私の場合、SSL証明書チェーンが壊れていました。このような問題は、SSLチェッカーを使用して、またはSSLLabsを使用してさらに中間的にテストできます。しかし、これがどのように起こり得るか私に尋ねないでください。私には全く手がかりがありません。

とにかく、SSL証明書を再インストールした後、「WebViewの信頼されていないSSL証明書」に関するすべてのエラーが最終的になくなりました。また、onReceivedSslError(...)の@Overrideを削除し、handler.proceed()を削除しました。これにより、私のアプリがGoogle Playストアで拒否されませんでした(再度)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.