Se connecter aux services web locaux à partir d’émulateurs Android et de simulateurs iOS

Browse sample. Parcourir l'exemple

De nombreuses applications mobiles et de bureau consomment des services web. Pendant la phase de développement du logiciel, il est courant de déployer un service web localement et de le consommer à partir d’une application fonctionnant dans l’émulateur Android ou le simulateur iOS. Cela évite d’avoir à déployer le service web sur un point de terminaison hébergé et permet une expérience de débogage simple, car l’application et le service web s’exécutent localement.

Les applications d’interface utilisateur d’application multiplateforme .NET (.NET MAUI) qui s’exécutent sur Windows ou MacCatalyst peuvent consommer ASP.NET services web Core qui s’exécutent localement sur HTTP ou HTTPS sans aucun travail supplémentaire, à condition que vous ayez approuvé votre certificat de développement. Toutefois, un travail supplémentaire est nécessaire lorsque l’application s’exécute dans l’émulateur Android ou le simulateur iOS, et que le processus est différent selon que le service web s’exécute sur HTTP ou HTTPS.

Adresse de l’ordinateur local

L’émulateur Android et le simulateur iOS fournissent tous deux un accès aux services web s’exécutant sur HTTP ou HTTPS sur votre ordinateur local. Mais ils utilisent chacun une adresse d’ordinateur local différente.

Android

Chaque instance de l’émulateur Android est isolée des interfaces réseau de votre ordinateur de développement et s’exécute derrière un routeur virtuel. Un appareil émulé ne peut donc pas voir votre ordinateur de développement ou d’autres instances de l’émulateur sur le réseau.

Cependant, le routeur virtuel de chaque émulateur gère un espace de réseau spécial qui inclut des adresses préallouées, l’adresse 10.0.2.2 servant d’alias vers votre interface de bouclage hôte (127.0.0.1 sur votre ordinateur de développement). Par conséquent, étant donné un service web local qui expose une opération GET via l’URI relatif /api/todoitems/, une application fonctionnant sur l’émulateur Android peut consommer l’opération en envoyant une requête GET à http://10.0.2.2:<port>/api/todoitems/ ou https://10.0.2.2:<port>/api/todoitems/.

iOS

Le simulateur iOS utilise le réseau de l’ordinateur hôte. Par conséquent, les applications exécutées dans le simulateur peuvent se connecter aux services web s’exécutant sur votre ordinateur local via l’adresse IP des machines ou via le nom d’hôte localhost. Par exemple, étant donné un service web local qui expose une opération GET via l’URI relatif /api/todoitems/, une application fonctionnant sur le simulateur iOS peut consommer l’opération en envoyant une requête GET à http://localhost:<port>/api/todoitems/ ou https://localhost:<port>/api/todoitems/.

Remarque

Lors de l’exécution d’une application .NET MAUI dans le simulateur iOS à partir de Windows, l’application s’affiche dans le simulateur iOS distant pour Windows. Toutefois, l’application s’exécute sur le Mac associé. Par conséquent, il n’existe aucun accès localhost à un service web s’exécutant dans Windows pour une application iOS s’exécutant sur un Mac.

Services web locaux s’exécutant sur HTTP

Une application .NET MAUI exécutée dans l’émulateur Android ou le simulateur iOS peut consommer un service web ASP.NET Core exécuté localement via HTTP. Pour ce faire, configurez votre projet d’application .NET MAUI et votre projet de service web core ASP.NET Core pour autoriser le trafic HTTP en texte clair.

Dans le code qui définit l’URL de votre service web local dans votre application .NET MAUI, vérifiez que l’URL du service web spécifie le schéma HTTP et le nom d’hôte correct. La classe DeviceInfo peut être utilisée pour détecter la plateforme sur laquelle l’application est en cours d’exécution. Le nom d’hôte correct peut ensuite être défini comme suit :

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

Pour plus d’informations sur la classe DeviceInfo, consultez Informations sur l’appareil.

En outre, pour exécuter votre application sur Android, vous devez ajouter la configuration de sécurité réseau requise et exécuter votre application sur iOS, vous devez désactiver Apple Transport Security (ATS). Pour plus d’informations, consultez configuration de la sécurité réseau Android et configuration iOS ATS.

Vous devez également vous assurer que votre ASP.NET service web Core est configuré pour autoriser le trafic HTTP. Pour ce faire, ajoutez un profil HTTP à la section profiles de launchSettings.json dans votre projet de service web core ASP.NET :

{
  ...
  "profiles": {
    "http": {
      "commandName": "Project",
      "dotnetRunMessages": true,
      "launchBrowser": true,
      "launchUrl": "api/todoitems",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    ...
  }
}

Une application MAUI .NET s’exécutant dans l’émulateur Android ou le simulateur iOS peut ensuite utiliser un service web ASP.NET Core qui s’exécute localement sur HTTP, à condition que ce service web soit lancé avec le profil http.

Configuration de la sécurité réseau Android

Pour activer le trafic local en texte clair sur Android, vous devez créer un fichier de configuration de sécurité réseau. Pour ce faire, ajoutez un nouveau fichier XML nommé network_security_config.xml au dossier Platforms\Android\Resources\xml de votre projet d’application .NET MAUI. Le fichier XML doit spécifier la configuration suivante :

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">10.0.2.2</domain>
  </domain-config>
</network-security-config>

Remarque

Vérifiez que l’action de génération du fichier network_security_config.xml est définie sur AndroidResource.

Ensuite, configurez la propriété networkSecurityConfig sur le nœud d’application dans le fichier Platforms\Android\AndroidManifest.xml dans votre projet d’application .NET MAUI :

<?xml version="1.0" encoding="utf-8"?>
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config" ...>
        ...
    </application>
</manifest>

Pour plus d’informations sur les fichiers de configuration de sécurité réseau, consultez configuration de sécurité réseau sur developer.android.com.

Configuration de l’ATS iOS

Pour activer le trafic local en texte clair sur iOS, vous devez désactiver Apple Transport Security (ATS) dans votre application .NET MAUI. Pour ce faire, ajoutez la configuration suivante au fichier Platforms\iOS\Info.plist dans votre projet d’application .NET MAUI :

<key>NSAppTransportSecurity</key>    
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Pour plus d’informations sur ATS, consultez Prévention des connexions réseaux non sécurisées sur developer.apple.com.

Services web locaux s’exécutant sur HTTPS

Une application .NET MAUI exécutée dans l’émulateur Android ou le simulateur iOS peut consommer un service web ASP.NET Core exécuté localement via HTTPS. Le processus d’activation est le suivant :

  1. Approuvez le certificat de développement auto-signé sur votre ordinateur. Pour plus d’informations, voir Confirmer votre certificat de développement.
  2. Spécifiez l’adresse de votre ordinateur local. Pour plus d’informations, consultez Spécifier l’adresse de l’ordinateur local.
  3. Contournez la vérification de sécurité du certificat de développement local. Pour plus d’informations, consultez Contourner la vérification de sécurité du certificat.

Chacun de ces points va être abordé à tour de rôle.

Ayez confiance en votre certificat de développement

L’installation du kit de développement logiciel (SDK) .NET Core installe le certificat de développement HTTPS ASP.NET Core dans votre magasin de certificats utilisateur local. Mais même s’il a été installé, le certificat n’est pas approuvé. Pour approuver le certificat, effectuez cette étape unique afin d’exécuter l’outil dotnet dev-certs :

dotnet dev-certs https --trust

La commande suivante fournit de l’aide sur l’outil dev-certs :

dotnet dev-certs https --help

Sinon, lorsque vous exécutez un projet ASP.NET Core 2.1 (ou version ultérieure) qui utilise HTTPS, Visual Studio détecte si le certificat de développement est manquant et vous propose de l’installer et de l’approuver.

Remarque

Le certificat de développement HTTPS ASP.NET Core est auto-signé.

Pour plus d’informations sur l’activation du protocole HTTPS local sur votre ordinateur, consultez Activer HTTPS localement.

Spécifier l’adresse de l’ordinateur local

Dans le code qui définit l’URL de votre service web local dans votre application .NET MAUI, vérifiez que l’URL du service web spécifie le schéma HTTPS et le nom d’hôte correct. La classe DeviceInfo peut être utilisée pour détecter la plateforme sur laquelle l’application est en cours d’exécution. Le nom d’hôte correct peut ensuite être défini comme suit :

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

Pour plus d’informations sur la classe DeviceInfo, consultez Informations sur l’appareil.

Contourner la vérification de sécurité du certificat

Si vous tentez d’appeler un service web sécurisé local à partir d’une application .NET MAUI exécutée dans un émulateur Android, un message java.security.cert.CertPathValidatorException indiquant que l’ancre d’approbation pour le chemin d’accès de certification n’a pas été trouvée. De même, la tentative d’appel d’un service web sécurisé local à partir d’une application .NET MAUI exécutée dans un simulateur iOS entraîne une erreur NSURLErrorDomain avec un message indiquant que le certificat pour le serveur n’est pas valide. Ces erreurs se produisent parce que le certificat de développement HTTPS local est auto-signé et que les certificats auto-signés ne sont pas approuvés par Android ou iOS. Par conséquent, il est nécessaire d’ignorer les erreurs SSL lorsqu’une application consomme un service web sécurisé local.

Pour ce faire, transmettez des versions configurées des classes natives HttpMessageHandler au constructeur, ce qui indique à la classe HttpClient d’approuver la communication HttpClient localhost via HTTPS. La classe HttpMessageHandler est une classe abstraite, dont l’implémentation sur Android est fournie par la classe, et dont l’implémentation AndroidMessageHandler sur iOS est fournie par la classe abstraiteNSUrlSessionHandler.

L’exemple suivant montre une classe qui configure la classe AndroidMessageHandler sur Android et la classe sur iOS pour approuver la communication NSUrlSessionHandler localhost sur HTTPS :

public class HttpsClientHandlerService
{
    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.");
#endif
    }

#if IOS
    public bool IsHttpsLocalhost(NSUrlSessionHandler sender, string url, Security.SecTrust trust)
    {
        if (url.StartsWith("https://localhost"))
            return true;
        return false;
    }
#endif
}

Sur Android, la méthode GetPlatformMessageHandler renvoie un objet AndroidMessageHandler. La méthode GetPlatformMessageHandler définit la propriété ServerCertificateCustomValidationCallback sur l’objet AndroidMessageHandler sur un rappel qui ignore le résultat de la sécurité des certificats case activée pour le certificat de développement HTTPS local.

Sur iOS, la méthode GetPlatformMessageHandler retourne un objet NSUrlSessionHandler qui définit sa propriété TrustOverrideForUrl sur un délégué nommé IsHttpsLocalHost qui correspond à la signature du ou de la délégué(e) NSUrlSessionHandler.NSUrlSessionHandlerTrustOverrideForUrlCallback. Le ou la délégué(e) IsHttpsLocalHost retourne true lorsque l’URL commence par https://localhost.

L’objet résultant HttpClientHandler peut ensuite être passé en tant qu’argument au constructeur HttpClient pour les builds de débogage :

#if DEBUG
            HttpsClientHandlerService handler = new HttpsClientHandlerService();
            HttpClient client = new HttpClient(handler.GetPlatformMessageHandler());
#else
            client = new HttpClient();
#endif

Une application .NET MAUI exécutée dans l’émulateur Android ou le simulateur iOS peut ensuite consommer un service web ASP.NET Core exécuté localement via HTTPS.