Usare le funzionalità di rete specifiche della piattaforma

Completato

La classe HttpClient fornisce un'astrazione della connessione alla rete. Un'app che usa questa classe è indipendente dallo stack di rete della piattaforma nativa. I modelli .NET MAUI associano la classe HttpClient al codice che utilizza lo stack di rete nativo di ogni piattaforma. In questo modo, un'applicazione può sfruttare le funzionalità di ottimizzazione e configurazione di rete specifiche della piattaforma. Questo è particolarmente importante quando è necessario configurare un'applicazione client per la connessione sicura a un servizio Web REST.

In questa unità si apprenderà come configurare un'applicazione client HTTP per usare le funzionalità di protezione di rete fornite dalla piattaforma sottostante.

Configurare App Transport Security in iOS

App Transport Security (ATS) è una funzionalità iOS che richiede l'uso di TLS versione 1.2 o successiva per ogni comunicazione di rete eseguita attraverso lo stack di rete nativo. Gli algoritmi di crittografia moderni impediranno la divulgazione delle informazioni qualora una delle chiavi a lungo termine fosse compromessa.

Se l'app non osserva queste regole, l'accesso alla rete verrà negato. Per risolvere questo problema, sono disponibili due opzioni. È possibile modificare l'endpoint in modo che risulti conforme ai criteri di App Transport Security oppure è possibile rifiutare esplicitamente l'uso di App Transport Security.

Per rifiutare esplicitamente App Transport Security, aggiungere una nuova chiave denominata NSAppTransportSecurity al file Info.plist . Il file Info.plist è disponibile nella cartella iOS della cartella Platforms del progetto in Esplora soluzioni. Questa chiave è in realtà un dizionario. Aggiungere al dizionario un'altra chiave denominata NSExceptionDomains, che contiene un elemento figlio per ognuno degli endpoint di destinazione. Ogni endpoint può avere una propria configurazione, che specifica le funzionalità da consentire o meno. È possibile aggiungere questa chiave usando l'editor plist generico in Visual Studio oppure aprendola come file XML.

Screenshot of left context menu with the open menu item selected. On the right is the window Visual Studio, X M L (text) editor is highlighted.

Ecco un esempio di configurazione per un endpoint in formato XML:

<key>NSAppTransportSecurity</key>
<dict>
   <key>NSExceptionDomains</key>
      <dict>
      <key>dotnet.microsoft.com</key>
      <dict>
        <key>NSExceptionMinimumTLSVersion</key>
        <string>TLSv1.0</string>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
      </dict>
   </dict>
</dict>

Questo esempio aggiunge un'eccezione all'endpoint in dotnet.microsoft.com. Se si esegue il debug di un servizio in locale nel computer di sviluppo, è possibile rifiutare esplicitamente App Transport Security per il traffico locale con la NSAllowsLocalNetworking chiave come indicato di seguito:

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

Se non è possibile identificare tutti gli endpoint, disabilitare App Transport Security per tutti gli endpoint non specificati usando la chiave NSAllowsArbitraryLoads:

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

Sono disponibili altre opzioni che possono essere aggiunte per specificare in modo più dettagliato la modalità del rifiuto esplicito. Ulteriori indicazioni non rientrano nell'ambito di questo modulo.

Configurare la sicurezza di rete in Android

Android ha un modello di sicurezza simile a iOS per le comunicazioni di rete. Il modello è stato introdotto con Android 9 (livello API 28). Il traffico non crittografato (non HTTPS) viene disabilitato per impostazione predefinita quando l'applicazione è destinata ad Android 9 (livello API 28) o superiore. Questo criterio potrebbe influire sul ciclo di sviluppo se l'app deve scaricare un'immagine o un file in un server che non è stato configurato per HTTPS. Inoltre, potrebbe essere sufficiente provare a eseguire il debug dell'applicazione in locale e non si vogliono installare i certificati di sviluppo. Si potrebbero avere requisiti aziendali rigorosi che tutto il traffico Web in tutte le versioni di Android è sempre HTTPS. La funzionalità Configurazione sicurezza di rete di Android consente di ottimizzare correttamente la sicurezza del traffico di rete in un'app.

Consentire il traffico non crittografato

Per consentire il traffico di testo non crittografato, creare un nuovo file XML nella cartella Resources/xml denominata network_security_config.xml (potrebbe anche essere necessario creare la cartella xml ). La cartella Resources si trova nella cartella della piattaforma Android in Esplora soluzioni. All'interno di questo file, aggiungere un elemento network-security-config con un elemento figlio domain-config. La configurazione seguente consente il traffico non crittografato per un dominio specifico e per un indirizzo IP:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">10.0.2.2</domain> <!-- Debug port -->
    <domain includeSubdomains="true">microsoft.com</domain>
  </domain-config>
</network-security-config>

È possibile rafforzare la sicurezza dell'app limitando il traffico di testo non crittografato in tutte le versioni di Android indipendentemente dal framework di destinazione. A tale scopo, impostare la cleartextTrafficPermitted proprietà dell'elemento domain-config su false. Questa impostazione di configurazione blocca tutto il traffico non HTTPS.

Per il riconoscimento del file network_security_config.xml da parte dell'app, configurare la proprietà networkSecurityConfig per il nodo application nel file AndroidManifest.xml che si trova nella cartella Properties:

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

È possibile specificare altre opzioni se è necessario indicare con più precisione come rifiutare esplicitamente la sicurezza del trasporto.

Eseguire il debug delle app in locale

Un importante vantaggio offerto dalla creazione di applicazioni per dispositivi mobili con Visual Studio è dato dalla possibilità di eseguire applicazioni di questo tipo e sottoporle a debug usando il simulatore iOS o l'emulatore Android. Queste app possono usare ASP.NET servizi Web Core in esecuzione in locale ed esposti tramite HTTP.

Le applicazioni in esecuzione nel simulatore iOS possono connettersi ai servizi Web HTTP locali tramite l'indirizzo IP del computer o tramite il nome host localhost. L'applicazione deve rifiutare esplicitamente ATS specificando almeno NSAllowsLocalNetworking. Ad esempio, dato un servizio Web HTTP locale che espone un'operazione GET tramite l'URI relativo /api/todoitems/, un'applicazione in esecuzione nel simulatore iOS può utilizzare l'operazione inviando una richiesta GET a http://localhost:<port>/api/todoitems/.

Le applicazioni in esecuzione nell'emulatore Android possono connettersi ai servizi Web HTTP locali tramite l'indirizzo 10.0.2.2. Questo indirizzo è un alias per l'interfaccia di loopback dell'host (127.0.0.1 nel computer di sviluppo). È necessario configurare anche una configurazione di sicurezza di rete per questo indirizzo IP specifico. Ad esempio, dato un servizio Web HTTP locale che espone un'operazione GET tramite l'URI relativo /api/todoitems/, un'applicazione in esecuzione nell'emulatore Android può utilizzare l'operazione inviando una richiesta GET a http://10.0.2.2:/api/todoitems/.

Nota

I servizi Web ASP.NET Core in esecuzione in modalità test sull'host locale devono disabilitare i reindirizzamenti HTTPS escludendo l'istruzione app.UseHttpsRedirection(); tramite un commento nel file Startup.cs.

Rilevare il sistema operativo

Un'app può determinare la piattaforma sulla quale in esecuzione usando la classe DeviceInfo. Nell'esempio seguente l'applicazione imposta la variabile BaseAddress su un valore diverso, a seconda che sia in esecuzione su Android:

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