diff --git a/docs/data-cloud/local-web-services.md b/docs/data-cloud/local-web-services.md index 51a026d26..6d9e527e1 100644 --- a/docs/data-cloud/local-web-services.md +++ b/docs/data-cloud/local-web-services.md @@ -1,7 +1,7 @@ --- title: "Connect to local web services from Android emulators and iOS simulators" description: "Learn how a .NET MAUI app running in the Android emulator or iOS simulator can consume a ASP.NET Core web service running locally." -ms.date: 06/19/2024 +ms.date: 10/07/2024 --- # Connect to local web services from Android emulators and iOS simulators @@ -189,57 +189,24 @@ For more information about the class, s Attempting to invoke a local secure web service from a .NET MAUI app running in an Android emulator will result in a `java.security.cert.CertPathValidatorException` being thrown, with a message indicating that the trust anchor for the certification path hasn't been found. Similarly, attempting to invoke a local secure web service from a .NET MAUI app running in an iOS simulator will result in an `NSURLErrorDomain` error with a message indicating that the certificate for the server is invalid. These errors occur because the local HTTPS development certificate is self-signed, and self-signed certificates aren't trusted by Android or iOS. Therefore, it's necessary to ignore SSL errors when an app consumes a local secure web service. -This can be accomplished by passing configured versions of the native `HttpMessageHandler` classes to the `HttpClient` constructor, which instruct the `HttpClient` class to trust localhost communication over HTTPS. The `HttpMessageHandler` class is an abstract class, whose implementation on Android is provided by the `AndroidMessageHandler` class, and whose implementation on iOS is provided by the `NSUrlSessionHandler` class. - -The following example shows a class that configures the `AndroidMessageHandler` class on Android and the `NSUrlSessionHandler` class on iOS to trust localhost communication over HTTPS: +This can be accomplished by configuring an instance of with a custom , which instructs the class to trust localhost communication over HTTPS. The following example shows how to create an instance of that will ignore localhost certificate validation errors: ```csharp -public class HttpsClientHandlerService +var handler = new HttpClientHandler(); + +#if DEBUG +handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { - public HttpMessageHandler GetPlatformMessageHandler() - { -#if ANDROID - var handler = new Xamarin.Android.Net.AndroidMessageHandler(); - handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => - { - if (cert != null && cert.Issuer.Equals("CN=localhost")) - return true; - return errors == System.Net.Security.SslPolicyErrors.None; - }; - return handler; -#elif IOS - var handler = new NSUrlSessionHandler - { - TrustOverrideForUrl = IsHttpsLocalhost - }; - return handler; -#else - throw new PlatformNotSupportedException("Only Android and iOS supported."); + if (cert != null && cert.Issuer.Equals("CN=localhost")) + return true; + return errors == System.Net.Security.SslPolicyErrors.None; +}; #endif - } -#if IOS - public bool IsHttpsLocalhost(NSUrlSessionHandler sender, string url, Security.SecTrust trust) - { - return url.StartsWith("https://localhost"); - } -#endif -} +var client = new HttpClient(handler); ``` -On Android, the `GetPlatformMessageHandler` method returns an `AndroidMessageHandler` object. The `GetPlatformMessageHandler` method sets the `ServerCertificateCustomValidationCallback` property on the `AndroidMessageHandler` object to a callback that ignores the result of the certificate security check for the local HTTPS development certificate. - -On iOS, the `GetPlatformMessageHandler` method returns a `NSUrlSessionHandler` object that sets its `TrustOverrideForUrl` property to a delegate named `IsHttpsLocalHost` that matches the signature of the `NSUrlSessionHandler.NSUrlSessionHandlerTrustOverrideForUrlCallback` delegate. The `IsHttpsLocalHost` delegate returns `true` when the URL starts with `https://localhost`. - -The resulting `HttpClientHandler` object can then be passed as an argument to the `HttpClient` constructor for debug builds: - -```csharp -#if DEBUG - HttpsClientHandlerService handler = new HttpsClientHandlerService(); - HttpClient client = new HttpClient(handler.GetPlatformMessageHandler()); -#else - client = new HttpClient(); -#endif -``` +> [!IMPORTANT] +> The code above ignores localhost certificate validation errors, but only in debug builds. This approach avoids security incidents in production builds. A .NET MAUI app running in the Android emulator or iOS simulator can then consume an ASP.NET Core web service that's running locally over HTTPS.