將驗證新增至 Xamarin.iOS 應用程式
注意
此產品已淘汰。 如需使用 .NET 8 或更新版本的專案取代專案,請參閱 Community Toolkit Datasync 連結庫。
在本教學課程中,您會使用 Microsoft Entra ID,將Microsoft驗證新增至 TodoApp 專案。 完成本教學課程之前,請確定您已 建立專案,並部署後端。
注意
由於 iOS 應用程式需要金鑰鏈存取,因此您必須設定 iOS 佈建設定檔。 布建配置檔需要實際的 iOS 裝置或付費的 Apple 開發人員帳戶(如果使用模擬器)。 如果您因為這項限制而無法使用驗證,您可以略過本教學課程,並繼續將 離機存取新增至應用程式。
提示
雖然我們使用 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) 來要求這類令牌,並將登入的使用者授權給後端服務。
設定原生用戶端應用程式
您可以使用用戶端連結庫,例如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
方案,並將 TodoApp.iOS
項目設定為啟始專案。 將 Microsoft 識別庫 (MSAL) 新增至 TodoApp.iOS
專案:
將 Microsoft 識別連結庫 (MSAL) 新增至平台專案:
以滑鼠右鍵按下項目,然後選取 [管理 NuGet 套件...。
選取 [流覽] 索引標籤。
在搜尋方塊中輸入
Microsoft.Identity.Client
,然後按 Enter 鍵。選取
Microsoft.Identity.Client
結果,然後按兩下 [安裝]。接受許可協議以繼續安裝。
將原生用戶端標識碼和後端範圍新增至組態。
開啟 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>"
};
}
將 <client-id>
取代為您在註冊 Microsoft Entra ID 中註冊用戶端應用程式時收到的 Native Client Application ID,並將 <scope>
取代為您在註冊服務應用程式時 公開 API 時所複製的 Web API 範圍。
在 TodoApp.iOS
項目中開啟 ViewControllers\HomeViewController.cs
。 新增下列 using
語句:
using Microsoft.Datasync.Client;
using Microsoft.Identity.Client;
using System.Diagnostics;
using System.Linq;
在 HomeViewController
類別中,新增屬性:
public IPublicClientApplication IdentityClient { get; set; }
調整建構函式以讀取:
public HomeViewController() {
Title = "Todo Items";
TodoService = new RemoteTodoService(GetAuthenticationToken);
TodoService.TodoItemsUpdated += OnTodoItemsUpdated;
}
將 GetAuthenticationToken
方法新增至 類別:
public async Task<AuthenticationToken> GetAuthenticationToken()
{
if (IdentityClient == null)
{
IdentityClient = PublicClientApplicationBuilder.Create(Constants.ApplicationId)
.WithAuthority(AzureCloudInstance.AzurePublic, "common")
.WithRedirectUri($"msal{Constants.ApplicationId}://auth")
.WithIosKeychainSecurityGroup("com.microsoft.adalcache")
.Build();
}
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()
.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()
方法可與 Microsoft Identity Library (MSAL) 搭配運作,以取得適合將登入使用者授權給後端服務的存取令牌。 接著,此函式會傳遞至 RemoteTodoService
以建立用戶端。 如果驗證成功,就會產生 AuthenticationToken
,其中包含授權每個要求所需的數據。 如果沒有,則會改為產生過期的不正確令牌。
將下列程式代碼新增至 AppDelegate
類別底部:
[Export("application:openURL:options:")]
public bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
{
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
return true;
}
將金鑰鏈存取新增至 Entitlements.plist
:
開啟
Entitlements.plist
檔案。選取 Keychain。
選取 [在密鑰鏈群組中新增。
輸入
com.microsoft.adalcache
作為值:
將自訂權利新增至專案:
以滑鼠右鍵按下
TodoApp.iOS
項目,然後選取 [[屬性]。選擇 [iOS 套件組合簽署。
選取 [自定義權利] 字段旁的 [...] 按鈕。
選取 [
Entitlements
],然後選取 [[開啟]。按 Ctrl+S 儲存專案。
測試應用程式
注意
由於 iOS 應用程式需要金鑰鏈存取權,因此您必須設定佈建配置檔。 布建配置檔需要實際裝置或付費的Apple開發人員帳戶(如果使用模擬器)。
將 TodoApp.iOS
設定為啟始專案,然後建置並執行應用程式。 當應用程式啟動時,系統會提示您登入應用程式。 在第一次執行時,系統會要求您同意應用程式。 驗證完成後,應用程式會正常執行。
後續步驟
接下來,實作離線存放區,設定您的應用程式以離線運作。