Herstellen einer Verbindung mit lokalen Webdiensten über iOS-Simulatoren und Android-Emulatoren
Webdienste werden von vielen mobilen Anwendungen genutzt. Während der Entwicklungsphase ist es üblich, einen Webdienst lokal bereitzustellen und aus einer mobilen Anwendung zu nutzen, die im iOS-Simulator oder Android-Emulator ausgeführt wird. Auf diese Weise wird die Notwendigkeit vermieden, den Webdienst an einem gehosteten Endpunkt bereitzustellen, und es wird eine unkomplizierte Debugerfahrung ermöglicht, weil sowohl die mobile Anwendung als auch der Webdienst lokal ausgeführt werden.
Mobile Anwendungen, die im iOS-Simulator oder Android-Emulator ausgeführt werden, können wie folgt ASP.NET Core-Webdienste nutzen, die lokal ausgeführt und über HTTP verfügbar gemacht werden:
- Im iOS-Simulator ausgeführte Anwendungen können eine Verbindung mit den lokalen HTTP-Webdiensten über die IP-Adresse Ihres Computers oder über den
localhost
-Hostnamen herstellen. Beispielsweise kann eine Anwendung, die im iOS-Simulator ausgeführt wird, vorausgesetzt, dass ein lokaler HTTP-Webdienst einen GET-Vorgang über den relativen URI/api/todoitems/
verfügbar macht, den Vorgang nutzen, indem sie eine GET-Anforderung anhttp://localhost:<port>/api/todoitems/
sendet. - Anwendungen, die im Android-Emulator ausgeführt werden, können eine Verbindung mit lokalen HTTP-Webdiensten über die Adresse
10.0.2.2
herstellen, bei der es sich um einen Alias für Ihre Host-Loopbackschnittstelle handelt (127.0.0.1
auf Ihrem Entwicklungscomputer). Beispielsweise kann eine Anwendung, die im Android-Emulator ausgeführt wird, vorausgesetzt, dass ein lokaler HTTP-Webdienst einen GET-Vorgang über den relativen URI/api/todoitems/
verfügbar macht, den Vorgang nutzen, indem sie eine GET-Anforderung anhttp://10.0.2.2:<port>/api/todoitems/
sendet.
Bei einer Anwendung, die im iOS-Simulator oder Android-Emulator ausgeführt wird sind jedoch zusätzliche Arbeiten notwendig, damit diese lokale Webdienste nutzen kann, die über HTTPS verfügbar gemacht werden. Für dieses Szenario gehen Sie wie folgt vor:
- Erstellen Sie ein selbstsigniertes Entwicklungszertifikat auf Ihrem Computer. Weitere Informationen finden Sie unter Erstellen eines Entwicklungszertifikats.
- Konfigurieren Sie Ihr Projekt so, dass es den entsprechenden
HttpClient
-Netzwerkstapel für Ihren Debugbuild verwendet. Weitere Informationen finden Sie unter Konfigurieren Ihres Projekts. - Geben Sie die Adresse Ihres lokalen Computers an. Weitere Informationen finden Sie unter Angeben der Adresse des lokalen Computers.
- Umgehen Sie die Sicherheitsüberprüfung des lokalen Entwicklungszertifikats. Weitere Informationen finden Sie unter Umgehen der Zertifikatsicherheitsüberprüfung.
Jeder Aspekt wird nacheinander erläutert.
Erstellen eines Entwicklungszertifikats
Durch das Installieren des ASP.NET Core SDK wird das ASP.NET Core-HTTPS-Entwicklungszertifikat im lokalen Benutzerzertifikatspeicher installiert. Allerdings ist das Zertifikat, auch wenn es installiert wurde, nicht vertrauenswürdig. Damit das Zertifikat vertrauenswürdig wird, führen Sie den folgenden, einmaligen Schritt durch, um das dotnet-Tool dev-certs
auszuführen:
dotnet dev-certs https --trust
Der folgende Befehl stellt Hilfe zum dev-certs
-Tool bereit:
dotnet dev-certs https --help
Alternativ erkennt Visual Studio, wenn Sie ein ASP.NET Core 2.1-Projekt (oder höher) ausführen, das HTTPS verwendet, ob das Entwicklungszertifikat fehlt, und bietet an, es zu installieren und ihm zu vertrauen.
Hinweis
Das ASP.NET Core-HTTPS-Entwicklungszertifikat ist selbstsigniert.
Weitere Informationen zum Aktivieren von lokalem HTTPS auf Ihrem Computer finden Sie unter Aktivieren von lokalem HTTPS.
Konfigurieren des Projekts
Xamarin-Anwendungen, die unter iOS und Android ausgeführt werden, können angeben, welcher Netzwerkstapel von der HttpClient
-Klasse verwendet wird, wobei ein veralteter Netzwerkstapel und native Netzwerkstapel zur Auswahl stehen. Der verwaltete Stapel kann bietet ein hohes Maß an Kompatibilität mit vorhandenem .NET-Code, ist aber auf TLS 1.0 beschränkt und kann langsamer sein sowie zu einer größeren ausführbaren Datei führen. Die nativen Stapel können schneller sein und höhere Sicherheit gewährleisten, stellen aber eventuell nicht alle Funktionen der HttpClient
-Klasse bereit.
iOS
Xamarin-Anwendungen, die unter iOS ausgeführt werden, können den verwalteten Netzwerkstapel verwenden oder die nativen Netzwerkstapel CFNetwork
oder NSUrlSession
. Standardmäßig verwenden neue iOS-Plattformprojekte den Netzwerkstapel NSUrlSession
, um TLS 1.2 zu unterstützen, und verwenden native APIs für eine bessere Leistung und eine kleinere ausführbare Datei. Weitere Informationen finden Sie unter HttpClient- und SSL/TLS-Implementierungsselektor für iOS/macOS.
Android
Xamarin-Anwendungen, die unter Android ausgeführt werden, können den verwalteten Netzwerkstapel HttpClient
verwenden oder den nativen Netzwerkstapel AndroidClientHandler
. Standardmäßig verwenden neue Android-Plattformprojekte den Netzwerkstapel AndroidClientHandler
, um TLS 1.2 zu unterstützen, und verwenden native APIs für eine bessere Leistung und eine kleinere ausführbare Datei. Weitere Informationen zu Android-Netzwerkstapeln finden Sie unter HttpClient-Stapel und SSL/TLS-Implementierungsselektor für Android.
Angeben der Adresse des lokalen Computers
iOS-Simulator und Android-Emulator gewähren beide Zugriff auf sichere Webdienste, die auf Ihrem lokalen Computer ausgeführt werden. Die Adresse des lokalen Computers ist jedoch für jeden anders.
iOS
Der iOS-Simulator verwendet das Netzwerk des Hostcomputers. Daher können im Simulator ausgeführte Anwendungen eine Verbindung mit Webdiensten, die auf Ihrem lokalen Computer ausgeführt werden, über die IP-Adresse Ihres Computers oder über den localhost
-Hostnamen herstellen. Beispielsweise kann eine Anwendung, die im iOS-Simulator ausgeführt wird, vorausgesetzt, dass ein lokaler, sicherer Webdienst einen GET-Vorgang über den relativen URI /api/todoitems/
verfügbar macht, den Vorgang nutzen, indem sie eine GET-Anforderung an https://localhost:<port>/api/todoitems/
sendet.
Hinweis
Wenn eine mobile Anwendung im iOS-Simulator aus Windows heraus ausgeführt wird, wird die Anwendung im iOS-Remotesimulator für Windows angezeigt. Die Anwendung wird allerdings auf dem gekoppelten Mac ausgeführt. Es gibt also für eine iOS-Anwendung, die auf einem Mac ausgeführt wird, keinen localhost-Zugriff auf einen Webdienst, der unter Windows ausgeführt wird.
Android
Jede Instanz des Android-Emulators ist von den Netzwerkschnittstellen Ihres Entwicklungscomputers isoliert und wird hinter einem virtuellen Router ausgeführt. Aus diesem Grund kann ein emuliertes Gerät Ihren Entwicklungscomputer oder andere Emulatorinstanzen im Netzwerk nicht sehen.
Der virtuelle Router für jeden Emulator verwaltet jedoch einen speziellen Netzwerkadressraum, der vorab zugeordnete Adressen enthält,wobei die 10.0.2.2
-Adressen ein Alias für Ihre Host-Loopback-Schnittstelle sind („127.0.0.1“ auf Ihrem Entwicklungscomputer). Deshalb kann eine Anwendung, die im Android-Emulator ausgeführt wird, vorausgesetzt, dass ein lokaler, sicherer Webdienst einen GET-Vorgang über den relativen URI /api/todoitems/
verfügbar macht, den Vorgang nutzen, indem sie eine GET-Anforderung an https://10.0.2.2:<port>/api/todoitems/
sendet.
Erkennen des Betriebssystems
Die DeviceInfo
-Klasse kann verwendet werden, um die Plattform zu erkennen, auf der die Anwendung ausgeführt wird. Der entsprechende Hostname, der Zugriff auf lokale, sichere Webdienste ermöglicht, kann dann wie folgt festgelegt werden:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Weitere Informationen zur DeviceInfo
-Klasse finden Sie unter Xamarin.Essentials: Geräteinformationen.
Umgehen der Zertifikatsicherheitsüberprüfung
Der Versuch, einen lokalen, sicheren Webdienst aus einer Anwendung aufzurufen, die im iOS-Simulator oder Android-Emulator ausgeführt wird, führt dazu,dass eine HttpRequestException
-Ausnahme ausgelöst wird, selbst wenn auf jeder Plattform der verwaltete Netzwerkstapel verwendet wird. Der Grund hierfür ist, dass das lokale HTTPS-Entwicklungszertifikat selbstsigniert ist und selbstsignierte Zertifikate in iOS und Android nicht vertrauenswürdig sind. Aus diesem Grund ist es erforderlich, SSL-Fehler zu ignorieren, wenn eine Anwendung einen lokalen, sicheren Webdienst nutzt. Hierfür können Sie die verwalteten oder nativen Netzwerkstapel unter iOS und Android verwenden, indem Sie die Eigenschaft ServerCertificateCustomValidationCallback
in einem HttpClientHandler
-Objekt auf einen Rückruf festlegen, der das Ergebnis der Zertifikatsicherheitsüberprüfung für das lokale HTTPS-Entwicklungszertifikat ignoriert:
// This method must be in a class in a platform project, even if
// the HttpClient object is constructed in a shared project.
public HttpClientHandler GetInsecureHandler()
{
HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
{
if (cert.Issuer.Equals("CN=localhost"))
return true;
return errors == System.Net.Security.SslPolicyErrors.None;
};
return handler;
}
In diesem Codebeispiel wird das Ergebnis der Serverzertifikatvalidierung zurückgegeben, wenn das Zertifikat, das validiert wurde, kein localhost
-Zertifikat ist. Für dieses Zertifikat wird das Ergebnis der Validierung ignoriert, und true
wird zurückgegeben, was anzeigt, dass das Zertifikat gültig ist. Das resultierende HttpClientHandler
-Objekt sollte als Argument an den HttpClient
-Konstruktor für Debugbuilds übergeben werden:
#if DEBUG
HttpClientHandler insecureHandler = GetInsecureHandler();
HttpClient client = new HttpClient(insecureHandler);
#else
HttpClient client = new HttpClient();
#endif
Ermöglichen von HTTP-Klartext-Datenverkehr
Optional können Sie Ihre iOS- und Android-Projekte so konfigurieren, dass HTTP-Klartext-Datenverkehr zugelassen ist. Wenn der Back-End-Dienst für HTTP-Datenverkehr konfiguriert ist, können Sie HTTP in den Basis-URLs angeben und dann die Projekte so konfigurieren, dass sie Klartext-Datenverkehr zulassen:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Deaktivieren von iOS-ATS
Um unter iOS lokalen Klartext-Datenverkehr zu ermöglichen, sollten Sie ATS deaktivieren, indem Sie Folgendes zu Ihrer Datei Info.plist hinzufügen:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Konfiguration der Netzwerksicherheit unter Android
Um unter Android lokalen Klartext-Datenverkehr zu ermöglichen, sollten Sie eine Konfiguration der Netzwerksicherheit erstellen, indem Sie im Ordner Resources/xml eine neue XML-Datei namens network_security_config.xml hinzufügen. Die XML-Datei sollte die folgende Konfiguration angeben:
<?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>
Konfigurieren Sie dann die Eigenschaft networkSecurityConfig im Knoten Anwendung im Android-Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
Stellen Sie sicher, dass die Buildaktion als AndroidResource festgelegt ist, andernfalls wird die XML-Datei zur Buildzeit nicht gefunden.