I've implemented onReceivedSslError
method in my WebViewClient to properly handle invalid https certificate in webview:
@Override
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
final AlertDialog.Builder builder = new AlertDialog.Builder(WebActivity.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", (dialog, which) -> handler.proceed());
builder.setNegativeButton("cancel", (dialog, which) -> handler.cancel());
final AlertDialog dialog = builder.create();
dialog.show();
}
When the webview loads my webpage the SslError.SSL_UNTRUSTED
error is being detected. However if I open the same exact url in chrome (both desktop or mobile) the certificate is considered valid and trusted:
Why is this happening?
For me this was an issue with the server I was trying to reach. It had a broken intermediate certificate chain. It was the redirect server that had a broken chain. When there is a broken chain the webview has no way to resolve because it does not know where to look for the correct cert.
Use this tool to check for common misconfigurations. Be sure to check any redirects as well.
Android does not support Authority Information Access
And therefore there is no AIA Fetching
But?!.. it works in browsers Yes, It works in browsers because all browsers carry around a list of intermediates to fall back on when the cert has a broken chain.
Solution: Fix certificate chain on server.
Even for me it was giving SSL_UNTRUSTED when the cert was throwing invalid CN(SSL_IDMISMATCH) on android chrome. Added network-security-config and all seemed to work fine. For me I installed a user-ca which wasnt being picked up by webview.
Added this snippet of code, which allowed me to use user-ca installed in user credentials.
<network-security-config>
<base-config>
<trust-anchors>
<!-- Trust preinstalled CAs -->
<certificates src="system" />
<!-- Additionally trust user added CAs -->
<certificates src="user" />
</trust-anchors>
</base-config>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With