Подключение к локальным веб-службам из iOS Simulator и Android Emulator
Многие мобильные приложения используют веб-службы. На этапе разработки веб-службу обычно развертывают локально и подключаются к ней из мобильного приложения, выполняемого в iOS Simulator или Android Emulator. Это избавляет от необходимости развертывать веб-службу в размещенной конечной точке и позволяет упростить процесс отладки, так как и мобильное приложение, и веб-служба выполняются локально.
Мобильные приложения, выполняемые в iOS Simulator или Android Emulator, могут использовать веб-службы ASP.NET Core, запущенные в локальной среде и предоставляемые по протоколу HTTP следующим образом:
- Приложения, выполняемые в iOS Simulator, могут подключаться к локальным веб-службам HTTP, используя IP-адрес компьютера или имя узла
localhost
. Например, если имеется локальная веб-служба HTTP, которая предоставляет операцию GET по относительному URI/api/todoitems/
, то приложение, работающее в iOS Simulator, может использовать операцию путем отправки запроса GET кhttp://localhost:<port>/api/todoitems/
. - Приложения, работающие в Android Emulator, могут подключаться к локальной веб-службе HTTP по адресу
10.0.2.2
, который является псевдонимом для интерфейса замыкания узла на себя (127.0.0.1
на компьютере разработки). Например, если имеется локальная веб-служба HTTP, которая предоставляет операцию GET по относительному URI/api/todoitems/
, то приложение, работающее в Android Emulator, может использовать операцию путем отправки запроса GET кhttp://10.0.2.2:<port>/api/todoitems/
.
Но приложению, выполняемому в iOS Simulator или Android Emulator, нужна доработка, чтобы оно могло использовать локальную веб-службу, предоставляемую по протоколу HTTPS. В этом сценарии процесс выглядит следующим образом:
- Создайте самозаверяющий сертификат разработки на своем компьютере. Дополнительные сведения см. в разделе Создание сертификата разработки.
- Настройте проект на использование соответствующего сетевого стека
HttpClient
для отладочной сборки. Дополнительные сведения см. в разделе Настройка проекта. - Укажите адрес своего локального компьютера. Дополнительные сведения см. в разделе Указание адреса локального компьютера.
- Выполните обход проверки безопасности сертификата разработки. Дополнительные сведения см. в разделе Обход проверки безопасности сертификата.
Далее последовательно рассматриваются все эти этапы.
Создание сертификата разработки
При установке пакета SDK для .NET Core в локальное хранилище сертификатов пользователя устанавливается сертификат разработки HTTPS ASP.NET Core. Но устанавливаемый сертификат не является доверенным. Чтобы сделать его доверенным, выполните следующее однократное действие для запуска средства .NET dev-certs
.
dotnet dev-certs https --trust
Следующая команда вызывает справку по средству dev-certs
.
dotnet dev-certs https --help
Кроме того, при запуске проекта ASP.NET Core 2.1 (или следующих версий), использующего протокол HTTPS, Visual Studio проверяет наличие сертификата разработки и предлагает установить его и сделать доверенным.
Примечание.
Сертификат разработки HTTPS ASP.NET Core является самозаверяющим.
Дополнительные сведения о включении протокола HTTPS в локальной среде на компьютере см. в разделе Включение локального HTTPS.
Настройка проекта
В приложении Xamarin для iOS и Android с помощью класса HttpClient
можно указать, какой сетевой стек использовать: управляемый сетевой стек или собственный сетевой стек. Управляемый стек обеспечивает высокий уровень совместимости с существующим кодом .NET, но ограничен протоколом TLS 1.0, может выполняться медленнее и стать причиной большого размера исполняемого файла. Собственный стек может выполнятся быстрее и обеспечивать лучшую безопасность, но при этом не предоставлять все функциональные возможности класса HttpClient
.
iOS
Приложения Xamarin под управлением iOS могут использовать управляемый сетевой стек или собственные сетевые стеки CFNetwork
или NSUrlSession
. По умолчанию новые проекты для платформы iOS используют сетевой стек NSUrlSession
для поддержки протокола TLS 1.2 и собственные API для повышения производительности и уменьшения размера исполняемого файла. Дополнительные сведения см. в статье о селекторе реализации HttpClient и SSL/TLS для iOS и macOS.
Android
Приложения Xamarin под управлением Android могут использовать управляемый сетевой стек HttpClient
или собственный сетевой стек AndroidClientHandler
. По умолчанию новые проекты для платформы Android используют сетевой стек AndroidClientHandler
для поддержки протокола TLS 1.2 и собственные API для повышения производительности и уменьшения размера исполняемого файла. Дополнительные сведения о сетевых стеках Android см. в статье Стек HttpClient и селектор реализации SSL/TLS для Android.
Указание адреса локального компьютера
Как iOS Simulator, так и Android Emulator предоставляют доступ к защищенным веб-службам на локальном компьютере. Но адреса локального компьютера при этом будут разными.
iOS
iOS Simulator использует сеть главного компьютера. Таким образом, приложения, выполняемые в симуляторе, могут подключаться к веб-службам, работающим на локальном компьютере, используя IP-адрес компьютера или имя узла localhost
. Например, если имеется локальная защищенная веб-служба, которая предоставляет операцию GET по относительному URI /api/todoitems/
, то приложение, работающее в iOS Simulator, может использовать операцию путем отправки запроса GET к https://localhost:<port>/api/todoitems/
.
Примечание.
При запуске мобильного приложения в iOS Simulator из Windows приложение отображается в Remoted iOS Simulator для Windows. Но приложение выполняется на связанном компьютере Mac. Таким образом, у приложения iOS на компьютере Mac отсутствует доступ localhost к веб-службе, выполняющейся в Windows.
Android
Каждый экземпляр Android Emulator изолирован от сетевых интерфейсов компьютера разработки с помощью виртуального маршрутизатора. Таким образом, эмулируемое устройство не может видеть компьютер разработки или другие экземпляры эмулятора в сети.
Виртуальный маршрутизатор каждого эмулятора управляет специализированным сетевым пространством, которое имеет предварительно выделенные адреса, а адрес 10.0.2.2
является псевдонимом для интерфейса замыкания узла на себя (127.0.0.1 на компьютере разработки). Таким образом, если имеется локальная защищенная веб-служба, которая предоставляет операцию GET по относительному URI /api/todoitems/
, то приложение, работающее в Android Emulator, может использовать операцию путем отправки запроса GET к https://10.0.2.2:<port>/api/todoitems/
.
Определение операционной системы
С помощью класса DeviceInfo
можно определить платформу, на которой запущено приложение. Соответствующее имя узла, предоставляющего доступ к локальной защищенной веб-службе, можно задать следующим образом:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Дополнительные сведения о классе DeviceInfo
см. в разделе Xamarin. Essentials. Сведения об устройстве.
Обход проверки безопасности сертификата
Попытка вызвать локальную защищенную веб-службу из приложения, выполняемого в iOS Simulator или Android Emulator, приведет к исключению HttpRequestException
даже при использовании управляемого сетевого стека на любой из платформ. Это обусловлено тем, что локальный сертификат разработки HTTPS является самозаверяющим, а самозаверяющие сертификаты не являются доверенными в iOS и Android. Таким образом, необходимо игнорировать ошибки SSL, когда приложение использует локальную защищенную веб-службу. Это можно сделать, используя управляемый и собственный сетевые стеки в iOS и Android и задав в качестве значения свойства ServerCertificateCustomValidationCallback
объекта HttpClientHandler
обратный вызов, который игнорирует результат проверки безопасности локального сертификата разработки HTTPS.
// 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;
}
В этом примере кода результат проверки сертификата сервера возвращается тогда, когда прошедший проверку сертификат не является сертификатом localhost
. Для такого сертификата результат проверки игнорируется и возвращается значение true
, подтверждающее, что сертификат действителен. Полученный объект HttpClientHandler
должен передаваться в качестве аргумента в конструктор HttpClient
для отладочных сборок:
#if DEBUG
HttpClientHandler insecureHandler = GetInsecureHandler();
HttpClient client = new HttpClient(insecureHandler);
#else
HttpClient client = new HttpClient();
#endif
Включение HTTP-трафика с открытым текстом
При необходимости для проектов iOS и Android можно настроить разрешение HTTP-трафика с открытым текстом. Если для серверной службы настроено разрешение HTTP-трафика, в базовых URL-адресах можно указать HTTP, а затем настроить для проектов разрешение трафика с открытым текстом:
public static string BaseAddress =
DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";
Отказ от ATS в iOS
Чтобы включить в iOS локальный трафик с открытым текстом, следует отказаться от ATS, добавив следующий текст в файл Info.plist:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Конфигурация сетевой безопасности в Android
Чтобы включить в Android локальный трафик с открытым текстом, необходимо создать конфигурацию сетевой безопасности, добавив новый XML-файл с именем network_security_config.xml в папку Resources/xml. XML-файл должен содержать следующую конфигурацию:
<?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>
Затем настройте свойство networkSecurityConfig в узле приложения в манифесте Android:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config">
...
</application>
</manifest>
Убедитесь, что действие сборки задано как AndroidResource, в противном случае XML-файл не будет найден во время сборки.
Дополнительные ссылки
- Включение локального HTTPS
- HttpClient and SSL/TLS implementation selector for iOS/macOS (Селектор реализации HttpClient и SSL/TLS для iOS и macOS)
- HttpClient Stack and SSL/TLS Implementation selector for Android (Селектор реализации HttpClient и SSL/TLS для Android)
- Конфигурация сетевой безопасности в Android
- Защита транспорта приложения в iOS
- Xamarin.Essentials: сведения об устройстве