Windows(UWP) 앱에 인증 추가

이 자습서에서는 Microsoft Entra ID를 사용하여 TodoApp 프로젝트에 Microsoft 인증을 추가합니다. 이 자습서를 완료하기 전에 프로젝트를 만들고 백 엔드를 배포했는지 확인합니다.

Microsoft Entra ID를 인증에 사용하지만 Azure Mobile Apps에서 원하는 모든 인증 라이브러리를 사용할 수 있습니다.

백 엔드 서비스에 인증 추가

백 엔드 서비스는 표준 ASP.NET 6 서비스입니다. ASP.NET 6 서비스에 인증을 사용하도록 설정하는 방법을 보여 주는 자습서는 Azure Mobile Apps에서 작동합니다.

백 엔드 서비스에 대해 Microsoft Entra 인증을 사용하도록 설정하려면 다음을 수행해야 합니다.

  • Microsoft Entra ID로 애플리케이션을 등록합니다.
  • ASP.NET 6 백 엔드 프로젝트에 인증 검사 추가합니다.

응용 프로그램 등록

먼저 Microsoft Entra 테넌트에 웹 API를 등록하고 다음 단계를 수행하여 범위를 추가합니다.

  1. Azure Portal에 로그인합니다.

  2. 여러 테넌트에 액세스할 수 있는 경우 위쪽 메뉴에서 디렉터리 + 구독 필터를 사용하여 애플리케이션을 등록하려는 테넌트로 전환합니다.

  3. Microsoft Entra ID를 검색하여 선택합니다.

  4. 관리 아래에서 앱 등록>새 등록을 선택합니다.

    • 이름: 애플리케이션의 이름(예 : TodoApp 빠른 시작)을 입력합니다. 앱 사용자에게 이 이름이 표시됩니다. 나중에 변경할 수 있습니다.
    • 지원되는 계정 유형: 모든 조직 디렉터리의 계정(모든 Microsoft Entra 디렉터리 - 다중 테넌트) 및 개인 Microsoft 계정(예: Skype, Xbox)
  5. 등록을 선택합니다.

  6. 관리에서 API 표시>범위 추가를 선택합니다.

  7. 애플리케이션 ID URI의 경우 저장 및 계속을 선택하여 기본값을 적용합니다.

  8. 다음 세부 정보를 입력합니다.

    • 범위 이름: access_as_user
    • 동의할 수 있는 사람은 누구인가요?: 관리자 및 사용자
    • 관리자 동의 표시 이름: Access TodoApp
    • 관리자 동의 설명: Allows the app to access TodoApp as the signed-in user.
    • 사용자 동의 표시 이름: Access TodoApp
    • 사용자 동의 설명: Allow the app to access TodoApp on your behalf.
    • 상태: 사용
  9. 범위 추가를 선택하여 범위 추가를 완료합니다.

  10. 범위 값(Web API 범위라고 함)과 유사합니다 api://<client-id>/access_as_user . 클라이언트를 구성할 때 범위가 필요합니다.

  11. 개요를 선택합니다.

  12. Essentials 섹션(Web API 애플리케이션 ID 라고 함)의 애플리케이션(클라이언트) ID확인합니다. 백 엔드 서비스를 구성하려면 이 값이 필요합니다.

Visual Studio를 열고 프로젝트를 선택합니다 TodoAppService.NET6 .

  1. 프로젝트를 마우스 오른쪽 단추로 TodoAppService.NET6 클릭한 다음 NuGet 패키지 관리를 선택합니다.

  2. 새 탭에서 찾아보기를 선택한 다음 검색 상자에 Microsoft.Identity.Web을 입력합니다.

    Screenshot of adding the M S A L NuGet in Visual Studio.

  3. Microsoft.Identity.Web 패키지를 선택한 다음 Install 키를 누릅니.

  4. 프롬프트에 따라 패키지 설치를 완료합니다.

  5. Program.cs을(를) 여십시오. 문 목록에 using 다음을 추가합니다.

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
  1. 호출 바로 위에 다음 코드를 추가합니다 builder.Services.AddDbContext().
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
  1. 호출 바로 위에 다음 코드를 추가합니다 app.MapControllers().
app.UseAuthentication();
app.UseAuthorization();

이제 Program.cs이 다음과 같이 표시됩니다.

using Microsoft.AspNetCore.Datasync;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using TodoAppService.NET6.Db;
  
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
  
if (connectionString == null)
{
  throw new ApplicationException("DefaultConnection is not set");
}
  
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  .AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDatasyncControllers();
  
var app = builder.Build();
  
// Initialize the database
using (var scope = app.Services.CreateScope())
{
  var context = scope.ServiceProvider.GetRequiredService<AppDbContext>();
  await context.InitializeDatabaseAsync().ConfigureAwait(false);
}
  
// Configure and run the web service.
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
  1. 를 편집합니다 Controllers\TodoItemController.cs. 클래스에 [Authorize] 특성을 추가합니다. 클래스는 다음과 같습니다.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Datasync;
using Microsoft.AspNetCore.Datasync.EFCore;
using Microsoft.AspNetCore.Mvc;
using TodoAppService.NET6.Db;

namespace TodoAppService.NET6.Controllers
{
  [Authorize]
  [Route("tables/todoitem")]
  public class TodoItemController : TableController<TodoItem>
  {
    public TodoItemController(AppDbContext context)
      : base(new EntityTableRepository<TodoItem>(context))
    {
    }
  }
}
  1. 를 편집합니다 appsettings.json. 다음 블록을 추가합니다.
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },

<client-id> 앞에서 기록한 Web API 애플리케이션 ID바꿉니다. 완료되면 다음과 같이 표시됩니다.

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com",
    "ClientId": "<client-id>",
    "TenantId": "common"
  },
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=TodoApp;Trusted_Connection=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Azure에 서비스를 다시 게시합니다.

  1. 프로젝트를 마우스 오른쪽 단추로 TodoAppService.NET6 클릭한 다음 게시...를 선택합니다.
  2. 탭의 오른쪽 위 모서리에 있는 게시 단추를 선택합니다.

브라우저에서 https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0를 엽니다. 이제 서비스는 인증이 필요하다는 401 응답을 반환합니다.

Screenshot of the browser showing an error.

ID 서비스에 앱 등록

Microsoft 데이터 동기화 프레임워크는 HTTP 트랜잭션의 헤더 내에서 JWT(Json Web Token)를 사용하는 모든 인증 공급자를 기본적으로 지원합니다. 이 애플리케이션은 MSAL(Microsoft 인증 라이브러리) 을 사용하여 이러한 토큰을 요청하고 로그인한 사용자에게 백 엔드 서비스에 권한을 부여합니다.

네이티브 클라이언트 애플리케이션 구성

MSAL(Microsoft Identity Library)과 같은 클라이언트 라이브러리를 사용하여 앱에서 호스트되는 웹 API에 대한 인증을 허용하도록 네이티브 클라이언트를 등록할 수 있습니다.

  1. Azure Portal에서 Microsoft Entra ID>앱 등록>새 등록을 선택합니다.

  2. 애플리케이션 등록 페이지에서 다음을 수행합니다.

    • 앱 등록의 이름을 입력합니다. 이 이름을 사용하여 백 엔드 서비스에서 사용하는 이름과 native-quickstart 구분할 수 있습니다.
    • 모든 조직 디렉터리(모든 Microsoft Entra 디렉터리 - 다중 테넌트) 및 개인 Microsoft 계정(예: Skype, Xbox)에서 계정을 선택합니다.
    • 리디렉션 URI에서:
      • 공용 클라이언트 선택 (모바일 및 데스크톱)
      • URL 입력 quickstart://auth
  3. 등록을 선택합니다.

  4. API 사용 권한>사용 권한 추가>내 API를 선택합니다.

  5. 백 엔드 서비스에 대해 이전에 만든 앱 등록을 선택합니다. 앱 등록이 표시되지 않으면 access_as_user 범위를 추가했는지 확인합니다.

    Screenshot of the scope registration in the Azure portal.

  6. 사용 권한 선택에서 access_as_user 선택한 다음, 권한 추가를 선택합니다.

  7. 인증>모바일 및 데스크톱 애플리케이션을 선택합니다.

  8. 옆에 있는 확인란을 https://login.microsoftonline.com/common/oauth2/nativeclient선택합니다.

  9. 옆에 있는 msal{client-id}://auth 확인란을 선택합니다(애플리케이션 ID로 바꾸기 {client-id} ).

  10. URI 추가를 선택한 다음, 필드에 추가 URI를 추가 http://localhost 합니다.

  11. 페이지 아래쪽에서 저장을 선택합니다.

  12. 개요를 선택합니다. 모바일 앱을 구성하는 데 필요한 애플리케이션(클라이언트) ID(네이티브 클라이언트 애플리케이션 ID라고 함)를 기록해 둡니다.

세 가지 리디렉션 URL을 정의했습니다.

  • http://localhost 는 WPF 애플리케이션에서 사용됩니다.
  • https://login.microsoftonline.com/common/oauth2/nativeclient 는 UWP 애플리케이션에서 사용됩니다.
  • msal{client-id}://auth 는 모바일(Android 및 iOS) 애플리케이션에서 사용됩니다.

앱에 Microsoft Identity Client 추가

TodoApp.sln Visual Studio에서 솔루션을 열고 프로젝트를 시작 프로젝트로 설정합니다TodoApp.UWP. 프로젝트에 MSAL(Microsoft Identity Library)TodoApp.UWP 추가합니다.

플랫폼 프로젝트에 MSAL(Microsoft Identity Library)을 추가합니다.

  1. 마우스 오른쪽 단추로 프로젝트를 클릭하고, NuGet 패키지 관리...를 선택합니다.

  2. 찾아보기 탭을 선택합니다.

  3. 검색 상자에 입력 Microsoft.Identity.Client 한 다음 Enter 키를 누릅니다.

  4. Microsoft.Identity.Client 결과를 선택한 다음 설치를 클릭합니다.

    Screenshot of selecting the MSAL NuGet in Visual Studio.

  5. 설치를 계속하려면 사용권 계약에 동의합니다.

네이티브 클라이언트 ID 및 백 엔드 범위를 구성에 추가합니다.

TodoApp.Data 프로젝트를 열고 파일을 편집합니다Constants.cs. 및 다음 상수를 추가합니다.ApplicationIdScopes

  public static class Constants
  {
      /// <summary>
      /// The base URI for the Datasync service.
      /// </summary>
      public static string ServiceUri = "https://demo-datasync-quickstart.azurewebsites.net";

      /// <summary>
      /// The application (client) ID for the native app within Microsoft Entra ID
      /// </summary>
      public static string ApplicationId = "<client-id>";

      /// <summary>
      /// The list of scopes to request
      /// </summary>
      public static string[] Scopes = new[]
      {
          "<scope>"
      };
  }

<client-id> 클라이언트 애플리케이션을 Microsoft Entra ID에 등록할 때 받은 Native Client 애플리케이션 ID<scope> 서비스 애플리케이션을 등록하는 동안 API 노출을 사용할 때 복사한 Web API 범위로 바꿉니다.

App.xaml.cs 프로젝트에서 파일을 TodoApp.UWP 엽니다.

파일 맨 위에 다음 using 문을 추가합니다.

using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

생성자와 TodoService 코드를 다음 코드로 바꿉다.

public App()
{
    InitializeComponent();
    Suspending += OnSuspending;

    IdentityClient = GetIdentityClient();
    TodoService = new RemoteTodoService(GetAuthenticationToken);
}

public static IPublicClientApplication IdentityClient { get; set; }

public ITodoService TodoService { get; }

public IPublicClientApplication GetIdentityClient()
{
    var identityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
        .WithAuthority(AzureCloudInstance.AzurePublic, "common")
        .WithUseCorporateNetwork(false)
        .WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
        .Build();
    return identityClient;
}

public async Task<AuthenticationToken> GetAuthenticationToken()
{
    var accounts = await IdentityClient.GetAccountsAsync();
    AuthenticationResult result = null;
    bool tryInteractiveLogin = false;

    try
    {
        result = await IdentityClient
            .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
            .ExecuteAsync()
            .ConfigureAwait(false);
    }
    catch (MsalUiRequiredException)
    {
        tryInteractiveLogin = true;
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
    }

    if (tryInteractiveLogin)
    {
        try
        {
            result = await IdentityClient
                .AcquireTokenInteractive(Constants.Scopes)
                .ExecuteAsync()
                .ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"MSAL Interactive Error: {ex.Message}");
        }
    }

    return new AuthenticationToken
    {
        DisplayName = result?.Account?.Username ?? "",
        ExpiresOn = result?.ExpiresOn ?? DateTimeOffset.MinValue,
        Token = result?.AccessToken ?? "",
        UserId = result?.Account?.Username ?? ""
    };
}

이 메서드는 GetAuthenticationToken() MSAL(Microsoft Identity Library)과 함께 작동하여 로그인한 사용자에게 백 엔드 서비스에 권한을 부여하는 데 적합한 액세스 토큰을 가져옵니다. 그런 다음 이 함수는 클라이언트를 RemoteTodoService 만들기 위해 전달됩니다. 인증에 성공 AuthenticationToken 하면 각 요청에 권한을 부여하는 데 필요한 데이터로 생성됩니다. 그렇지 않은 경우 만료된 잘못된 토큰이 대신 생성됩니다.

앱 테스트

F5 키를 눌러 앱을 실행할 수 있어야 합니다. 앱이 실행되면 인증을 요청하는 브라우저가 열립니다. 앱이 처음 실행되면 액세스에 동의하라는 메시지가 표시됩니다.

Screenshot of the Microsoft Entra consent request.

앱을 계속하려면 Yes를 누릅니다.

다음 단계

다음으로 오프라인 저장소를 구현하여 오프라인으로 작동하도록 애플리케이션을 구성합니다.

추가 참고 자료