플랫폼별 네트워크 기능 사용

완료됨

HttpClient 클래스는 네트워크에 대한 연결의 추상화를 제공합니다. 이 클래스를 사용하는 앱은 네이티브 플랫폼 네트워킹 스택과 독립적입니다. .NET MAUI 템플릿은 HttpClient 클래스를 각 플랫폼의 네이티브 네트워킹 스택에 활용하는 코드에 매핑합니다. 이를 통해 애플리케이션은 플랫폼별 네트워크 구성 및 최적화 기능을 활용할 수 있습니다. 이는 REST 웹 서비스에 안전하게 연결하도록 클라이언트 애플리케이션을 구성해야 하는 경우에 특히 중요합니다.

이 단원에서는 기본 플랫폼에서 제공하는 네트워크 보호 기능을 사용하도록 HTTP 클라이언트 애플리케이션을 구성하는 방법을 알아봅니다.

iOS의 앱 전송 보안 구성

ATS(앱 전송 보안)는 TLS 1.2 이상을 사용하기 위해 네이티브 HTTP 네트워크 스택을 통해 모든 네트워크 통신을 수행하도록 요구하는 iOS 기능입니다. 최신 암호화 알고리즘은 장기적인 키 중 하나가 손상된 경우 정보를 공개하지 않습니다.

앱이 이 규칙을 준수하지 않는 경우 네트워크 액세스가 거부됩니다. 이 문제를 해결하려면 두 가지 옵션이 있습니다. 앱 전송 보안 정책을 준수하도록 엔드포인트를 변경하거나 앱 전송 보안을 옵트아웃할 수 있습니다.

앱 전송 보안을 옵트아웃하려면 Info.plist 파일에 NSAppTransportSecurity라는 새 키를 추가합니다. 솔루션 탐색기에 있는 프로젝트의 Platforms 폴더에 있는 iOS 폴더에서 Info.plist 파일을 찾을 수 있습니다. 이 키는 실제로 사전입니다. 이 사전에 NSExceptionDomains라는 다른 키를 추가합니다. 이 키는 대상으로 지정할 각 엔드포인트에 대한 자식을 포함합니다. 각 엔드포인트에는 허용하거나 허용하지 않는 기능을 지정하는 자체 구성이 있을 수 있습니다. 이 키는 Visual Studio에서 일반 plist 편집기를 사용하거나 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.

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>

이 예제에서는 dotnet.microsoft.com에서 엔드포인트에 예외를 추가합니다. 개발 머신에서 서비스를 로컬로 디버깅하는 경우 다음과 같이 NSAllowsLocalNetworking 키를 사용하여 로컬 트래픽에 대해 앱 전송 보안을 옵트아웃할 수 있습니다.

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

일부 엔드포인트를 식별할 수 없는 경우 NSAllowsArbitraryLoads 키를 사용하여 모든 미지정 엔드포인트에 대해 앱 전송 보안을 사용하지 않도록 설정합니다.

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

옵트아웃하려는 방법을 좀 더 구체화하기 위해 추가할 수 있는 다른 옵션이 있습니다. 추가적인 지침은 이 모듈의 범위를 벗어납니다.

Android 네트워크 보안 구성

iOS와 마찬가지로 Android도 네트워크 통신과 유사한 보안 모델을 가지고 있습니다. 이 모델은 Android 9(API 수준 28)에서 도입되었습니다. 애플리케이션이 Android 9(API 수준 28) 이상을 타겟팅하는 경우 일반 텍스트(HTTPS 아님) 트래픽이 기본적으로 비활성화됩니다. 앱이 HTTPS에 대해 구성되지 않은 서버에서 이미지 또는 파일을 다운로드해야 하는 경우 이 정책은 개발 주기에 영향을 줄 수 있습니다. 또한 애플리케이션을 로컬로 디버깅하려고 하지만 개발 인증서의 설치는 원하지 않습니다. 모든 Android 버전의 모든 웹 트래픽이 항상 HTTPS이어야 한다는 강력한 비즈니스 요구 사항이 있을 수 있습니다. Android 네트워크 보안 구성 기능을 사용하면 앱에서 네트워크 트래픽 보안을 미세 조정할 수 있습니다.

일반 텍스트 트래픽 허용

일반 텍스트 트래픽을 허용하려면 Resources/xml 폴더에 network_security_config.xml이라는 새 XML 파일을 만듭니다(xml 폴더도 만들어야 할 수도 있음). Resources 폴더는 솔루션 탐색기의 Android 플랫폼 폴더에 있습니다. 이 파일 안에 domain-config 자식 요소가 있는 network-security-config 요소를 추가합니다. 다음 구성을 사용하면 특정 도메인 및 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>

대상 프레임워크에 관계없이 모든 Android 버전에서 일반 텍스트 트래픽을 제한하여 앱의 보안을 강화할 수 있습니다. domain-config 요소의 cleartextTrafficPermitted 속성을 false로 설정하면 됩니다. 이 구성 설정은 HTTPS가 아닌 모든 트래픽을 차단합니다.

앱이 network_security_config.xml 파일을 인식하도록, Properties 폴더에 있는 AndroidManifest.xml에서 application노드에 대해 networkSecurityConfig 속성을 구성합니다.

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

전송 보안을 옵트아웃하는 방법에 대해 보다 구체적으로 설명해야 하는 경우 추가 옵션을 지정할 수 있습니다.

로컬로 앱 디버그

Visual Studio를 사용하여 모바일 애플리케이션을 빌드할 때의 중요한 이점은 iOS 시뮬레이터 또는 Android 에뮬레이터를 사용하여 모바일 애플리케이션을 실행하고 디버그하는 기능입니다. 이러한 앱은 로컬로 실행되고 HTTP를 통해 노출되는 ASP.NET Core 웹 서비스를 사용할 수 있습니다.

iOS 시뮬레이터에서 실행 중인 애플리케이션은 컴퓨터 IP 주소 또는 localhost 호스트 이름을 통해 로컬 HTTP 웹 서비스에 연결할 수 있습니다. 애플리케이션은 최소 NSAllowsLocalNetworking을 지정하는 ATS를 옵트아웃해야 합니다. 예를 들어 /api/todoitems/ 상대 URI를 통해 GET 연산을 노출하는 로컬 HTTP 웹 서비스가 있는 경우, iOS 시뮬레이터에서 실행 중인 애플리케이션은 http://localhost:<port>/api/todoitems/GET 요청을 전송하여 해당 작업을 사용할 수 있습니다.

Android 에뮬레이터에서 실행되는 애플리케이션은 10.0.2.2 주소를 통해 로컬 HTTP 웹 서비스에 연결할 수 있습니다. 이 주소는 호스트 루프백 인터페이스(개발 머신의 127.0.0.1)에 대한 별칭입니다. 이 특정 IP 주소에 대한 네트워크 보안 구성도 설정해야 합니다. 예를 들어, /api/todoitems/ 상대 URI를 통해 GET 연산을 노출하는 로컬 HTTP 웹 서비스가 있는 경우, Android Emulator에서 실행 중인 애플리케이션은 http://10.0.2.2:/api/todoitems/GET 요청을 전송하여 해당 작업을 사용할 수 있습니다.

참고

로컬 호스트에서 테스트 중인 ASP.NET Core 웹 서비스는 Startup.cs 파일에서 app.UseHttpsRedirection(); 문을 주석 처리하여 HTTPS 리디렉션을 사용하지 않도록 설정해야 합니다.

운영 체제 검색

앱은 DeviceInfo 클래스를 사용하여 실행 중인 플랫폼을 확인할 수 있습니다. 다음 예제에서 애플리케이션은 Android에서 실행 중인지 여부에 따라 BaseAddress 변수를 다른 값으로 설정합니다.

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