xamarin.formswebviewandroid-webview

Android WebView does not use manually installed certificates


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
}

Solution

  • 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