Uso de características de red específicas de la plataforma
La clase HttpClient proporciona una abstracción de la conexión a la red. Una aplicación que usa esta clase es independiente de la pila de redes de plataforma nativa. Las plantillas de .NET MAUI asignan la clase HttpClient al código que utiliza la pila de redes nativa de cada plataforma. Esto permite que una aplicación aproveche las ventajas de las características de optimización y configuración de red específicas de la plataforma. Esto es especialmente importante cuando necesita configurar una aplicación cliente para conectarse de forma segura a un servicio web de REST.
En esta unidad aprenderá a configurar una aplicación cliente de HTTP para usar las capacidades de protección de red que proporcione la plataforma subyacente.
Configuración de la seguridad de transporte de aplicaciones en iOS
La Seguridad de transporte de aplicaciones (ATS) es una característica de iOS que requiere que todas las comunicaciones de red realizadas a través de la pila de red HTTP nativa usen TLS 1.2 o versiones posteriores. Los algoritmos de cifrado modernos no revelan información si una de las claves a largo plazo se encuentra en peligro.
Si la aplicación no cumple estas normas, se le denegará el acceso a la red. Para solucionar este problema, tiene dos opciones: puede cambiar el punto de conexión para que se adhiera a la directiva de Seguridad de transporte de aplicaciones o puede optar por no participar en la Seguridad de transporte de aplicaciones.
Para no participar en Seguridad de transporte de aplicaciones, agregue una nueva clave llamada NSAppTransportSecurity
al archivo Info.plist. Encontrará el archivo Info.plist en la carpeta iOS de la carpeta Plataformas que está en el proyecto del Explorador de soluciones. Esta clave es un diccionario. Agregue otra clave denominada NSExceptionDomains
a este diccionario. Esta contiene un elemento secundario para cada uno de los puntos de conexión que quiere establecer como destino. Cada punto de conexión puede tener su propia configuración y especifica qué características permite o no permite. Puede agregar esta clave mediante el editor plist genérico de Visual Studio o abriéndola como un archivo XML.
Esta es una configuración de ejemplo para un punto de conexión que se muestra como 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>
En este ejemplo se agrega una excepción al punto de conexión en dotnet.microsoft.com. Si está depurando un servicio de forma local en el equipo de desarrollo, puede optar por no participar en la Seguridad de transporte de aplicaciones para el tráfico local con la clave NSAllowsLocalNetworking
, tal como se indica a continuación:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
Si no es capaz de identificar todos los puntos de conexión, deshabilite la Seguridad de transporte de aplicaciones en todos los puntos de conexión sin especificar mediante la clave NSAllowsArbitraryLoads
:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Hay otras opciones que puede agregar para ser más específico sobre cómo quiere dejar de participar. Recuerde que estos detalles se encuentran fuera del ámbito de este módulo.
Configuración de la seguridad de red de Android
Al igual que iOS, Android tiene un modelo de seguridad similar en torno a la comunicación de red. Este modelo se introdujo con Android 9 (nivel de API 28). El tráfico de texto no cifrado (no HTTPS) está deshabilitado de forma predeterminada cuando la aplicación tiene como destino Android 9 (nivel de API 28) o superior. Esta directiva podría afectar al ciclo de desarrollo si la aplicación necesita descargar una imagen o un archivo en un servidor que no se haya configurado para HTTPS. Además, es posible que solo esté intentando depurar la aplicación localmente y no quiera instalar certificados de desarrollo. Es posible que tenga requisitos empresariales fuertes de que todo el tráfico web de todas las versiones de Android sea siempre HTTPS. La característica Configuración de seguridad de red de Android le permite ajustar con precisión la seguridad del tráfico de red en una aplicación.
Permisos del tráfico de texto no cifrado
Para permitir el tráfico de texto no cifrado, cree un nuevo archivo XML en la carpeta Resources/xml, denominado network_security_config.xml (es posible que también tenga que crear la carpeta xml). La carpeta Recursos se encuentra en la carpeta de la plataforma Android del Explorador de soluciones. En este archivo, agregue un elemento network-security-config
con un elemento secundario domain-config
. La siguiente configuración habilita el tráfico de texto no cifrado para un dominio específico y para una dirección 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>
Para reforzar la seguridad de la aplicación, también puede restringir el tráfico de texto no cifrado en todas las versiones de Android, independientemente de la plataforma de destino. Para ello, establezca la propiedad cleartextTrafficPermitted
del elemento domain-config
en false
. Esta configuración bloquea todo el tráfico que no sea HTTPS.
Para que la aplicación reconozca el archivo network_security_config.xml, configure la propiedad networkSecurityConfig
del nodo application
en AndroidManifest.xml que se encuentra en la carpeta Propiedades:
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application android:networkSecurityConfig="@xml/network_security_config" ...></application>
</manifest>
Puede especificar opciones adicionales si necesita ser más específico sobre cómo quiere dejar de participar en la seguridad del transporte.
Depuración de aplicaciones de forma local
Un beneficio importante de la compilación de aplicaciones móviles con Visual Studio es la capacidad de ejecutar y depurar aplicaciones móviles mediante el simulador de iOS o el emulador de Android. Estas aplicaciones pueden consumir servicios web de ASP.NET Core que se ejecutan localmente y se exponen a través de HTTP.
Las aplicaciones que se ejecutan en el simulador de iOS pueden conectarse a los servicios web HTTP locales a través de la dirección IP de la máquina o a través del nombre de host de localhost. La aplicación debe anular el uso de ATS especificando un mínimo de NSAllowsLocalNetworking
. Por ejemplo, dado un servicio web HTTP local que expone una operación GET
mediante el identificador URI relativo /api/todoitems/, una aplicación que se ejecute en el simulador de iOS puede consumir la operación por medio del envío de una solicitud GET
a http://localhost:<port>/api/todoitems/.
Las aplicaciones que se ejecutan en el emulador de Android pueden conectarse a servicios web HTTP locales a través de la dirección 10.0.2.2. Esta dirección es un alias para la interfaz de bucle invertido del host (127.0.0.1 en el equipo de desarrollo). También debe configurarse la seguridad de red para esta dirección IP específica. Por ejemplo, dado un servicio web HTTP local que expone una operación GET
mediante el identificador URI relativo /api/todoitems/, una aplicación que se ejecute en el emulador de Android puede consumir la operación por medio del envío de una solicitud GET
a http://10.0.2.2:/api/todoitems/.
Nota
Los servicios web de ASP.NET Core que se ejecutan en modo de prueba en el host local deben tener deshabilitadas las redirecciones HTTPS; para ello, hay que comentar la instrucción app.UseHttpsRedirection();
en el archivo Startup.cs.
Detección del sistema operativo
Una aplicación puede determinar en qué plataforma se está ejecutando mediante la clase DeviceInfo
. En el ejemplo siguiente, la aplicación establece la variable BaseAddress en un valor diferente, dependiendo de si se ejecuta en 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/";