Xamarin iOS - programmatically trusting CA (certificate authority)

Akmal Mursalimov 25 Reputation points
2023-07-11T07:57:05.8266667+00:00
Good afternoon. Could you help with the following problem? I need to connect a third-party certificate, for example "test.cer" for WebView to work correctly. 

In Android, I solved the problem as follows:

1. Added the certificate file to Android project to Resources/Raw, with the build action - AndroidResource.

2. Added an xml file network_security_config.xml with the following content:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
	<base-config>
		<trust-anchors>
			<certificates src="@raw/test"/> //The path to the certificate
			<certificates src="system"/>
		</trust-anchors>
	</base-config>
</network-security-config>

3. Added a android:networkSecurityConfig parameter to AndroidManifest:
<application android:label="MyAPP" android:icon="@mipmap/icon" android:networkSecurityConfig="@xml/network_security_config">

I don't understand how to do the same for an iOS project. Thank you in advance for your help.
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,337 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 74,641 Reputation points Microsoft Vendor
    2023-07-12T08:23:47.6+00:00

    Hello,

    Firstly, you can add next code to your Info.plist file to allow self signed certificate in iOS.(Before submitting app to the Appstore, please set"Allow Arbitrary Loads" to No.)

    Note that using self-signed certificates is generally not recommended for production scenarios. It is better to use certificates signed by a trusted certificate authority (CA) to ensure a secure connection.

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

    Or you can set specific domain in Info.plist:

    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>[YOUR BASE URL HERE]</key>
            <dict>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSAllowsArbitraryLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>
    

    Then you can create a custom renderer for webview. Then you can create a WebViewDelegate implement WKNavigationDelegate and INSUrlConnectionDataDelegate to allow ServerSecTrust

    [assembly: ExportRenderer(typeof(WebView), typeof(MyCustomWebview))]
    namespace XFCertificate.iOS
    {
        public class MyCustomWebview: ViewRenderer<WebView, WKWebView>
        {
            protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
            {
                base.OnElementChanged(e);
                if (Control == null)
                {
                    var webView = new WKWebView(Frame, new WKWebViewConfiguration());
                    webView.NavigationDelegate = new WebViewDelegate();
                   SetNativeControl(webView);
                }
                if (e.NewElement != null)
                {
                    Control.LoadRequest(new NSUrlRequest(new NSUrl(e.NewElement.Source.ToString())));
                }
            }
           
           
        }
        public class WebViewDelegate : WKNavigationDelegate, INSUrlConnectionDataDelegate
        {
            public override void DidReceiveAuthenticationChallenge(WKWebView webView, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
            {       
                completionHandler(NSUrlSessionAuthChallengeDisposition.UseCredential, new NSUrlCredential(challenge.ProtectionSpace.ServerSecTrust));
              
                return;
            }
        }
    }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.