將驗證新增至Uno Platform 應用程式
注意
此產品已淘汰。 如需使用 .NET 8 或更新版本的專案取代專案,請參閱 Community Toolkit Datasync 連結庫。
在本教學課程中,您會使用 Microsoft Entra ID,將Microsoft驗證新增至 TodoApp 專案。 完成本教學課程之前,請確定您已 建立專案,並部署後端。
提示
雖然我們使用 Microsoft Entra ID 進行驗證,但您可以使用任何您想要與 Azure Mobile Apps 搭配使用的驗證連結庫。
將驗證新增至後端服務
您的後端服務是標準 ASP.NET 6 服務。 任何示範如何啟用 ASP.NET 6 服務驗證與 Azure Mobile Apps 搭配運作的教學課程。
若要為後端服務啟用Microsoft Entra 驗證,您需要:
- 使用 Microsoft Entra 識別子註冊應用程式。
- 將驗證檢查新增至 ASP.NET 6 個後端專案。
註冊應用程式
首先,在您的 Microsoft Entra 租用戶中註冊 Web API,並遵循下列步驟來新增範圍:
登入 Azure 入口網站。
如果您有多個租使用者的存取權,請使用頂端功能表中的 [目錄 + 訂用帳戶] 篩選,切換至您要在其中註冊應用程式的租使用者。
搜尋並選擇 Microsoft Entra ID。
在 [[管理] 下,選取 [應用程式註冊],>[新增註冊]。
- 名稱:輸入應用程式的名稱;例如,TodoApp 快速入門。 您應用程式的使用者會看到此名稱。 您可以稍後加以變更。
- 支援的帳戶類型:任何組織目錄中的 帳戶(任何Microsoft Entra 目錄 - 多租使用者)和個人Microsoft帳戶(例如Skype、Xbox)
選取 [[註冊]。
在 [管理] 下,選取 [[公開 API>[新增範圍]。
針對 應用程式識別碼 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 應用程式識別碼)。 您需要此值來設定後端服務。
開啟 Visual Studio,然後選取 TodoAppService.NET6
專案。
以滑鼠右鍵按下
TodoAppService.NET6
項目,然後選取 [管理 NuGet 套件...。在新索引標籤中,選取 [流覽],然後在搜尋方塊中輸入 Microsoft.Identity.Web。
選擇
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 應用程式識別碼。 完成後,看起來應該像這樣:
{
"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
回應,表示需要驗證。
向身分識別服務註冊您的應用程式
Microsoft數據同步架構內建支援任何在 HTTP 交易標頭內使用 Json Web 令牌 (JWT) 的驗證提供者。 此應用程式會使用 Microsoft 驗證連結庫 (MSAL) 來要求這類令牌,並將登入的使用者授權給後端服務。 如需將 MSAL 整合到 Uno Platform 專案的詳細資訊,請檢閱其檔
設定原生用戶端應用程式
您可以使用用戶端連結庫,例如Microsoft身分識別連結庫(MSAL),註冊原生用戶端,以允許驗證裝載在應用程式中的Web API。
在 Azure 入口網站中,選取 [Microsoft [專案標識符]>[應用程式註冊]>[新增註冊]。
在 [註冊應用程式 頁面中:
- 輸入應用程式註冊 名稱。 您可能想要使用名稱
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}
)。選取 [[新增 URI],然後在字段中新增
http://localhost
以取得額外的 URI。選取頁面底部的 [儲存]。
選取 概觀。 記下 應用程式 (用戶端) 識別碼 (稱為 Native Client Application ID),因為您需要它才能設定行動應用程式。
我們已定義三個重新導向 URL:
- WPF 應用程式會使用
http://localhost
。 - UWP 應用程式會使用
https://login.microsoftonline.com/common/oauth2/nativeclient
。 - 行動裝置 (Android 和 iOS) 應用程式會使用
msal{client-id}://auth
。
將 Microsoft Identity Client 新增至您的應用程式
在 Visual Studio 中開啟 TodoApp.sln
方案。 將 Uno.WinUI.MSAL 新增至每個 TodoApp.Uno
專案:
在解決方案上按下滑鼠右鍵,然後選取 [[管理方案的 NuGet 套件...]。
選取 [流覽] 索引標籤。
在搜尋方塊中輸入
Uno.WinUI.MSAL
,然後按 Enter 鍵。選取
Uno.WinUI.MSAL
結果。在右側面板中,選取每個
TodoApp.Uno
專案。選擇 [[安裝]。
接受許可協議以繼續安裝。
使用相同的技術,將 Microsoft.Identity.Client 連結庫新增至每個 TodoApp.Uno
專案:
在搜尋方塊中輸入
Microsoft.Identity.Client
,然後按 Enter 鍵。選取
Microsoft.Identity.Client
結果。在右側面板中,選取每個
TodoApp.Uno
專案。選擇 [[安裝]。
接受許可協議以繼續安裝。
注意
請確定您安裝這兩個連結庫的最新版本。 最低版本號碼如下:
- Uno.WinUI.MSAL v4.9.20
- Microsoft.Identity.Client v4.54.1
將原生用戶端標識碼和後端範圍新增至組態。
開啟 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 Azure Active Directory
/// </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 Application ID,並將 <scope>
取代為您在註冊服務應用程式時 公開 API 時所複製的 Web API 範圍。
在 TodoApp.Uno
項目的頂端資料夾中開啟 MainPage.xaml.cs
檔案。
將下列 using
語句新增至檔案頂端:
using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;
using Uno.UI.MSAL;
以下欄程序代碼取代欄位和建構函式:
private readonly IPublicClientApplication _identityClient;
private readonly TodoListViewModel _viewModel;
private readonly ITodoService _service;
public MainPage() {
this.InitializeComponent();
_identityClient = PublicClientApplicationBuilder
.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
#if __IOS__ || __MACOS__ || __ANDROID__
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
#else
.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient")
#endif
#if __IOS__
.WithIosKeychainSecurityGroup("com.microsoft.adalcache")
#endif
.WithUnoHelpers()
.Build();
_service = new RemoteTodoService(GetAuthenticationToken);
_viewModel = new TodoListViewModel(this, _service);
mainContainer.DataContext = _viewModel;
}
將下列方法新增至 MainPage
類別:
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();
}
catch (MsalUiRequiredException)
{
tryInteractiveLogin = true;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"MSAL Silent Error: {ex.Message}");
}
if (tryInteractiveLogin)
{
try
{
result = await _identityClient
.AcquireTokenInteractive(Constants.Scopes)
.WithUnoHelpers()
.ExecuteAsync();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"MSAL Interactive Error: {ex.Message}");
}
}
return new AuthenticationToken
{
DisplayName = result?.Account?.Username ?? string.Empty,
ExpiresOn = result?.ExpiresOn ?? DateTimeOffset.MinValue,
Token = result?.AccessToken ?? string.Empty,
UserId = result?.Account?.Username ?? string.Empty
};
}
GetAuthenticationToken()
方法可與 Microsoft Identity Library (MSAL) 搭配運作,以取得適合將登入使用者授權給後端服務的存取令牌。 接著,此函式會傳遞至 RemoteTodoService
以建立用戶端。 如果驗證成功,就會產生 AuthenticationToken
,其中包含授權每個要求所需的數據。 如果沒有,則會改為產生過期的不正確令牌。
設定 Android 應用程式以進行驗證
開啟 TodoApp.Uno.Mobile
項目,然後展開 [Android
] 資料夾。 使用下列程式代碼建立新的類別 MsalActivity.Android.cs
(與現有的 MainActivity.Android.cs
一起):
using Android.Content;
using Microsoft.Identity.Client;
namespace TodoApp.Uno.Droid
{
[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}
(這與 Constants.ApplicationId
相同)。
如果您的專案以 Android 11 版(API 第 30 版)或更新版本為目標,您必須更新您的 TodoApp.Uno.Mobile/Android/AndroidManifest.xml
,並將下列 queries/intent
節點新增至 manifest
節點:
<manifest>
...
<queries>
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>
編輯 MainActivity.Android.cs
類別;新增 OnActivityResult
方法:
using Android.Views;
using Microsoft.Identity.Client;
namespace TodoApp.Uno.Droid
{
[Activity(
MainLauncher = true,
ConfigurationChanges = global::Uno.UI.ActivityHelper.AllConfigChanges,
WindowSoftInputMode = SoftInput.AdjustNothing | SoftInput.StateHidden
)]
public class MainActivity : Microsoft.UI.Xaml.ApplicationActivity
{
protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
}
}
}
當 Android 需要驗證時,它會取得身分識別客戶端,然後切換至開啟系統瀏覽器的內部活動。 驗證完成後,系統瀏覽器會重新導向至定義的重新導向 URL (msal{client-id}://auth
)。
MasalActvity
會擷取重新導向 URL,然後藉由呼叫 OnActivityResult()
切換回主要活動。
OnActivityResult()
方法會呼叫 MSAL 驗證協助程式來完成交易。
測試 Android 應用程式
將 TodoApp.Uno.Mobile
設定為啟始專案,選取 android 模擬器作為目標,然後按 F5 來建置並執行應用程式。 當應用程式啟動時,系統會提示您登入應用程式。 在第一次執行時,系統也會要求您同意應用程式。 驗證完成後,應用程式會正常執行。
後續步驟
接下來,實作離線存放區,設定您的應用程式以離線運作。