I have a WebView
in a Xamarin Forms application. It shows generated HTML which has references to resources on the intranet. These resources are TLS protected and a self signed certificate backs the secure communication.
The root-certificate is installed on the android device. Accessing it with google chrome works. However accessing it from WebView fails with an SSL error (3, untrusted).
For testing purposes, I changed the WebViewClient
and overwrote OnReceiveSslError
. There I check for my self signed certificate, allowing it manually (handler.Proceed
). This works.
However this gives me new issues such as that the Navigating-event on the Xamarin.Forms.WebView
does no more fire. Probably, I could also circumvent this problem, but everything seems a bit wrong.
To me it looks like as if the Android WebView
does not use the same certificate store as that Google Chrome does. Is this correct and is there a fix to this behavior, hopefully without the necessity to create a custom renderer for the WebView
control and introducing a whole bunch of potential new issues (such as the missing Navigating-event)?
Update according to Jessie Zhang's request
Broken Navigating Event
Attach in XAML a Navigating
event. Assign a custom renderer for the WebView
and in OnElementChanged
assign a custom WebviewClient
via SetWebViewClient
. This step breaks the Navigating
event, regardless whether the OnReceiveSslError
is overriden or not (see code below).
Certificate Error
Use a WebView and assign it a custom built HTML via HtmlWebViewSource
and embed some images which reference a https:// resource on a server with a self signed root-certificate (OpenSSL). Add the root certificate to the Android certificate store (via the User certificates applet). Although chrome and other clients accept now the https-resources, WebView
does not. It seems as it does not consider the manually installed root certificate.
As an additional information: When overriding the OnReceiveSslEvent
in WebViewClient, the certificate is available in the SslError
parameter, however not accepted.
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) {
base.OnElementChanged(e);
if (e.NewElement != null) {
Control.SetWebViewClient(
new BreakingWebViewClient()
);
}
}
class BreakingWebViewClient : WebViewClient{
// ... some code, but for breaking the Navigating-event, no code is necessary
}
I ran into the same issue in a native Android project, installed certificates were respected by Chrome but not in embedded web views.
To fix the problem I needed to define a network security configuration.
In AndroidManifest.xml add the following attribute to the application node:
android:networkSecurityConfig="@xml/network_security_config"
Then create the file xml/network_security_config.xml
with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system"/>
<certificates src="user"/>
</trust-anchors>
</base-config>
</network-security-config>
I believe the key line that fixes the problem is <certificates src="user"/>
as user certificates are not included in the default configuration according to the docs.
Network security configuration documentation can be found here: https://developer.android.com/privacy-and-security/security-config