.NET MAUI 앱에 인증 추가
메모
이 제품은 사용 중지되었습니다. .NET 8 이상을 사용하는 프로젝트를 대체하려면 Community Toolkit Datasync 라이브러리참조하세요.
이 자습서에서는 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를 등록하고 다음 단계에 따라 범위를 추가합니다.
Azure Portal로그인합니다.
여러 테넌트에 액세스할 수 있는 경우 위쪽 메뉴에서 디렉터리 + 구독 필터를 사용하여 애플리케이션을 등록하려는 테넌트로 전환합니다.
Microsoft Entra ID
검색하여 선택합니다. 관리 아래에서 새 등록앱 등록을 선택합니다. - 이름: 애플리케이션의 이름을 입력합니다. 예를 들어 TodoApp 빠른 시작. 앱 사용자에게 이 이름이 표시됩니다. 나중에 변경할 수 있습니다.
- 지원되는 계정 유형: 모든 조직 디렉터리(모든 Microsoft Entra 디렉터리 - 다중 테넌트)의 계정 및 개인 Microsoft 계정(예: Skype, Xbox)
등록선택합니다.
관리 아래에서 범위추가API 노출 선택합니다. 애플리케이션 ID URI경우 저장을 선택하고계속하여 기본값을 적용합니다.
다음 세부 정보를 입력합니다.
-
범위 이름:
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.
- 상태: 사용
-
범위 이름:
범위 추가를 완료하려면 범위 추가를 선택합니다.
api://<client-id>/access_as_user
(Web API 범위참조)와 유사한 범위 값을 확인합니다. 클라이언트를 구성할 때 범위가 필요합니다.개요선택합니다.
Essentials 섹션(Web API 애플리케이션 ID참조)의 애플리케이션(클라이언트) ID 확인합니다. 백 엔드 서비스를 구성하려면 이 값이 필요합니다.
Visual Studio를 열고 TodoAppService.NET6
프로젝트를 선택합니다.
TodoAppService.NET6
프로젝트를 마우스 오른쪽 단추로 클릭한 다음 NuGet 패키지 관리...선택합니다.새 탭에서찾아보기
선택한 다음 검색 상자에 microsoft.Identity.Web 입력합니다. 패키지를 선택한 다음 설치 누릅니다. 프롬프트에 따라 패키지 설치를 완료합니다.
Program.cs
엽니다.using
문 목록에 다음을 추가합니다.
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
-
builder.Services.AddDbContext()
호출 바로 위에 다음 코드를 추가합니다.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
builder.Services.AddAuthorization();
-
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();
-
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))
{
}
}
}
-
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에 서비스를 다시 게시합니다.
-
TodoAppService.NET6
프로젝트를 마우스 오른쪽 단추로 클릭한 다음 게시...선택합니다. - 탭의 오른쪽 위 모서리에서 게시 단추를 선택합니다.
브라우저를 열어 https://yoursite.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=3.0.0
. 이제 서비스는 인증이 필요하다는 401
응답을 반환합니다.
ID 서비스에 앱 등록
Microsoft 데이터 동기화 프레임워크는 HTTP 트랜잭션의 헤더 내에서 JWT(Json Web Token)를 사용하는 모든 인증 공급자를 기본적으로 지원합니다. 이 애플리케이션은 MSAL(Microsoft 인증 라이브러리) 사용하여 이러한 토큰을 요청하고 로그인한 사용자에게 백 엔드 서비스에 권한을 부여합니다.
네이티브 클라이언트 애플리케이션 구성
MSAL(Microsoft Identity Library)과 같은 클라이언트 라이브러리를 사용하여 앱에서 호스트되는 웹 API에 대한 인증을 허용하도록 네이티브 클라이언트를 등록할 수 있습니다.
Azure Portal 새 등록Microsoft Entra ID 앱 등록을 선택합니다. 애플리케이션 등록 페이지에서 다음을 수행합니다.
- 앱 등록에 대한 이름 입력합니다.
native-quickstart
이름을 사용하여 백 엔드 서비스에서 사용하는 이름과 구분할 수 있습니다. - 모든 조직 디렉터리(모든 Microsoft Entra 디렉터리 - 다중 테넌트) 및 개인 Microsoft 계정(예: Skype, Xbox)
계정을 선택합니다. -
리디렉션 URI:
- 공용 클라이언트(모바일 & 데스크톱)
- URL
quickstart://auth
입력합니다.
- 앱 등록에 대한 이름 입력합니다.
등록선택합니다.
API 사용 권한을 내 API 사용 권한을 추가합니다. 백 엔드 서비스에 대해 이전에 만든 앱 등록을 선택합니다. 앱 등록이 표시되지 않으면 access_as_user 범위를 추가했는지 확인합니다.
사용 권한 선택하고access_as_user 선택한 다음사용 권한 추가를 선택합니다. 모바일 및 데스크톱 애플리케이션 인증을 선택합니다. https://login.microsoftonline.com/common/oauth2/nativeclient
옆의 확인란을 선택합니다.msal{client-id}://auth
옆의 확인란을 선택합니다({client-id}
애플리케이션 ID로 대체).URI추가를 선택한 다음, 추가 URI를 위해 필드에
http://localhost
추가합니다.페이지 아래쪽에서 저장을 선택합니다.
개요선택합니다. 모바일 앱을 구성하는 데 필요한 애플리케이션(클라이언트) ID(Native Client 애플리케이션 ID참조)를 기록해 둡니다.
세 가지 리디렉션 URL을 정의했습니다.
-
http://localhost
WPF 애플리케이션에서 사용됩니다. -
https://login.microsoftonline.com/common/oauth2/nativeclient
UWP 애플리케이션에서 사용됩니다. -
msal{client-id}://auth
모바일(Android 및 iOS) 애플리케이션에서 사용됩니다.
앱에 Microsoft Identity Client 추가
Visual Studio에서 TodoApp.sln
솔루션을 열고 TodoApp.MAUI
프로젝트를 시작 프로젝트로 설정합니다.
MSAL(Microsoft Identity Library)TodoApp.MAUI
프로젝트에 추가합니다.
플랫폼 프로젝트에 MSAL(Microsoft Identity Library) 추가합니다.
프로젝트를 마우스 오른쪽 단추로 클릭한 다음 NuGet 패키지 관리...선택합니다.
찾아보기 탭을 선택합니다.
검색 상자에
Microsoft.Identity.Client
입력한 다음 Enter 키를 누릅니다.Microsoft.Identity.Client
결과를 선택한 다음 설치클릭합니다.설치를 계속하려면 사용권 계약에 동의합니다.
네이티브 클라이언트 ID 및 백 엔드 범위를 구성에 추가합니다.
TodoApp.Data
프로젝트를 열고 Constants.cs
파일을 편집합니다.
ApplicationId
및 Scopes
대한 상수를 추가합니다.
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>"
};
}
TodoApp.MAUI
프로젝트에서 MainPage.xaml.cs
클래스를 엽니다. 다음 using
문을 추가합니다.
using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
MainPage
클래스에서 새 속성을 추가합니다.
public IPublicClientApplication IdentityClient { get; set; }
읽을 생성자를 조정합니다.
public MainPage()
{
InitializeComponent();
TodoService = new RemoteTodoService(GetAuthenticationToken);
viewModel = new MainViewModel(this, TodoService);
BindingContext = viewModel;
}
클래스에 GetAuthenticationToken
메서드를 추가합니다.
public async Task<AuthenticationToken> GetAuthenticationToken()
{
if (IdentityClient == null)
{
#if ANDROID
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
.WithParentActivityOrWindow(() => Platform.CurrentActivity)
.Build();
#elif IOS
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithIosKeychainSecurityGroup("com.microsoft.adalcache")
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
.Build();
#else
IdentityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
.Build();
#endif
}
var accounts = await IdentityClient.GetAccountsAsync();
AuthenticationResult result = null;
bool tryInteractiveLogin = false;
try
{
result = await IdentityClient
.AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
.ExecuteAsync();
}
catch (MsalUiRequiredException)
{
tryInteractiveLogin = true;
}
catch (Exception ex)
{
Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
}
if (tryInteractiveLogin)
{
try
{
result = await IdentityClient
.AcquireTokenInteractive(Constants.Scopes)
.ExecuteAsync();
}
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
생성됩니다. 그렇지 않은 경우 만료된 잘못된 토큰이 대신 생성됩니다.
플랫폼 지정자가 있는 #if
영역을 사용하여 플랫폼별 옵션을 추가할 수 있습니다. 예를 들어 Android에서는 호출 페이지에서 전달되는 부모 활동을 지정해야 합니다.
인증을 위해 Android 앱 구성
다음 코드를 사용하여 새 클래스 Platforms\Android\MsalActivity.cs
만듭니다.
using Android.App;
using Android.Content;
using Microsoft.Identity.Client;
namespace TodoApp.MAUI
{
[Activity(Exported = true)]
[IntentFilter(new[] { Intent.ActionView },
Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
DataHost = "auth",
DataScheme = "msal{client-id}")]
public class MsalActivity : BrowserTabActivity
{
}
}
{client-id}
네이티브 클라이언트의 애플리케이션 ID(Constants.ApplicationId
동일)로 바꿉니다.
프로젝트가 Android 버전 11(API 버전 30) 이상을 대상으로 하는 경우Platforms/Android/AndroidManifest.xml
열고 다음 queries/intent
노드를 manifest
노드에 추가합니다.
<manifest>
...
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>
MauiProgram.cs
엽니다. 파일 맨 위에 다음 using
문을 포함합니다.
using Microsoft.Identity.Client;
작성기를 다음 코드로 업데이트합니다.
builder
.UseMauiApp<App>()
.ConfigureLifecycleEvents(events =>
{
#if ANDROID
events.AddAndroid(platform =>
{
platform.OnActivityResult((activity, rc, result, data) =>
{
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(rc, result, data);
});
});
#endif
})
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
iOS용 애플리케이션을 업데이트한 후 이 단계를 수행하는 경우 #if ANDROID
지정된 코드(#if
및 #endif
포함)를 추가합니다. 컴파일러는 컴파일 중인 플랫폼에 따라 올바른 코드 조각을 선택합니다. 이 코드는 iOS용 기존 블록 앞이나 뒤를 배치할 수 있습니다.
Android에서 인증이 필요한 경우 ID 클라이언트를 가져온 다음 시스템 브라우저를 여는 내부 활동으로 전환합니다. 인증이 완료되면 시스템 브라우저가 정의된 리디렉션 URL(msal{client-id}://auth
)로 리디렉션됩니다.
MsalActivity
리디렉션 URL을 트래핑한 다음, OnActivityResult()
호출하여 기본 활동으로 다시 전환합니다.
OnActivityResult()
메서드는 MSAL 인증 도우미를 호출하여 트랜잭션을 완료합니다.
Android 앱 테스트
TodoApp.MAUI
시작 프로젝트로 설정하고, android 에뮬레이터를 대상으로 선택한 다음, F5 눌러 앱을 빌드하고 실행합니다. 앱이 시작되면 앱에 로그인하라는 메시지가 표시됩니다. 첫 번째 실행에서는 앱에 동의하라는 메시지가 표시됩니다. 인증이 완료되면 앱이 정상적으로 실행됩니다.
Windows 앱 테스트
다음 단계
다음으로, 오프라인 저장소구현하는
추가 읽기
- 빠른 시작: Microsoft ID 플랫폼 사용하여 웹 API 보호
- MSAL.NET 사용하여 Xamarin Android에 대한
구성 요구 사항 및 문제 해결 팁 - 시나리오: 웹 API를 호출하는 모바일 애플리케이션