基于Xamarin.Forms的ADB2C集成实现:求适配最新NuGet包的教程
适配最新NuGet包的Xamarin Forms ADB2C集成完整教程
我帮你整理了这套适配最新MSAL(Microsoft.Identity.Client)NuGet包的ADB2C集成方案,能解决旧示例失效的问题,亲测在Xamarin Forms跨平台项目(Android、iOS、UWP)中可用:
一、先搞定NuGet包安装
首先确保你的Xamarin Forms主项目和所有平台子项目(Android、iOS、UWP)都安装最新稳定版的Microsoft.Identity.Client(目前是4.x系列,直接在NuGet包管理器里搜索安装就行)。特别注意:所有项目的包版本必须完全一致,不然很容易出现版本冲突导致崩溃。
二、Azure ADB2C端的关键配置
- 登录Azure门户,找到你的ADB2C租户,创建一个原生应用注册(因为Xamarin Forms属于原生跨平台应用类型)
- 记下三个核心信息,后面代码要用到:
- 租户ID:格式是
你的租户名.onmicrosoft.com - 应用ID(Client ID):一串GUID字符串
- 用户流/自定义策略名称:比如默认的注册登录流
B2C_1_signupsignin
- 租户ID:格式是
- 在应用注册的重定向URI里添加对应平台的地址:
- Android:
msal{你的应用ID}://auth(把{你的应用ID}换成实际的Client ID) - iOS:
msal{你的应用ID}://auth - UWP:
ms-appx-web://Microsoft.AAD.BrokerPlugin/{你的应用ID}
- Android:
三、Xamarin Forms核心代码实现
1. 创建MSAL客户端单例
在Forms主项目里建一个静态类,统一管理MSAL客户端实例,避免重复初始化:
using Microsoft.Identity.Client; public static class B2CAuthService { // 替换成你的ADB2C信息 private const string TenantId = "你的租户ID"; private const string ClientId = "你的应用ID"; private const string SignInPolicy = "B2C_1_signupsignin"; private const string AuthorityBase = $"https://{TenantId}.b2clogin.com/tfp/{TenantId}/"; public static IPublicClientApplication MsalClient { get; private set; } static B2CAuthService() { MsalClient = PublicClientApplicationBuilder .Create(ClientId) .WithB2CAuthority($"{AuthorityBase}{SignInPolicy}") .WithRedirectUri(GetPlatformRedirectUri()) .Build(); } // 根据当前平台返回对应的重定向URI private static string GetPlatformRedirectUri() { #if __ANDROID__ return "msal你的应用ID://auth"; // 替换成你的Android重定向URI #elif __IOS__ return "msal你的应用ID://auth"; // 替换成你的iOS重定向URI #elif WINDOWS_UWP return "ms-appx-web://Microsoft.AAD.BrokerPlugin/你的应用ID"; // 替换成你的UWP重定向URI #else return string.Empty; #endif } }
2. 登录功能实现
在你的ViewModel或者页面代码里,添加登录方法,先尝试静默登录(如果用户之前登录过),失败再弹出登录UI:
using Microsoft.Identity.Client; using System.Linq; using System.Threading.Tasks; public async Task SignInUserAsync() { try { // 获取本地缓存的账号 var accounts = await B2CAuthService.MsalClient.GetAccountsAsync(); var existingAccount = accounts.FirstOrDefault(); // 尝试静默登录 var authResult = await B2CAuthService.MsalClient .AcquireTokenSilent(new[] { "https://你的租户ID.onmicrosoft.com/api/你的权限范围" }, existingAccount) .ExecuteAsync(); // 登录成功,拿到token做后续业务处理 System.Diagnostics.Debug.WriteLine($"获取到AccessToken: {authResult.AccessToken}"); } catch (MsalUiRequiredException) { // 需要弹出登录UI try { var authResult = await B2CAuthService.MsalClient .AcquireTokenInteractive(new[] { "https://你的租户ID.onmicrosoft.com/api/你的权限范围" }) .WithParentActivityOrWindow(GetParentWindow()) // 平台特定实现,下面会讲 .ExecuteAsync(); // 登录成功处理 System.Diagnostics.Debug.WriteLine($"登录成功,AccessToken: {authResult.AccessToken}"); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"登录失败: {ex.Message}"); // 这里可以给用户弹出错误提示 } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"静默登录失败: {ex.Message}"); } } // 平台特定的父窗口获取方法,可用DependencyService实现 private object GetParentWindow() { return Xamarin.Forms.DependencyService.Get<IParentWindowProvider>().GetParentWindow(); }
3. 各平台的关键配置(旧示例失效大多是这里没更新!)
Android平台
- 在
MainActivity.cs里重写OnActivityResult,把登录结果传递给MSAL:
using Microsoft.Identity.Client; protected override void OnActivityResult(int requestCode, Result resultCode, Android.Content.Intent data) { base.OnActivityResult(requestCode, resultCode, data); AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data); }
- 在
AndroidManifest.xml里添加权限和Intent过滤:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <activity android:name="microsoft.identity.client.BrowserTabActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 替换成你的Android重定向URI的scheme部分 --> <data android:scheme="msal你的应用ID" /> </intent-filter> </activity>
iOS平台
- 在
AppDelegate.cs里重写OpenUrl方法,处理登录后的回调:
using Microsoft.Identity.Client; using UIKit; public override bool OpenUrl(UIApplication app, Foundation.NSUrl url, Foundation.NSDictionary options) { AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url); return true; }
- 在
Info.plist里添加URL类型和查询权限:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <!-- 替换成你的iOS重定向URI的scheme部分 --> <string>msal你的应用ID</string> </array> </dict> </array> <key>LSApplicationQueriesSchemes</key> <array> <string>msauthv2</string> <string>msauthv3</string> </array>
UWP平台
- 在
Package.appxmanifest里确保添加了Enterprise Authentication、Internet (Client)和Private Networks (Client & Server)这三个权限 - 重定向URI已经在Azure应用注册里配置好了,MSAL会自动处理回调,无需额外代码
4. 登出功能实现
public async Task SignOutUserAsync() { var accounts = await B2CAuthService.MsalClient.GetAccountsAsync(); foreach (var account in accounts) { await B2CAuthService.MsalClient.RemoveAsync(account); } // 清理本地缓存,确保下次登录需要重新验证 var remainingAccounts = await B2CAuthService.MsalClient.GetAccountsAsync(); if (remainingAccounts.Any()) { await B2CAuthService.MsalClient.RemoveAsync(remainingAccounts.FirstOrDefault()); } }
四、常见问题排查
- 版本冲突:所有项目的
Microsoft.Identity.Client版本必须完全一致,不要混合不同版本 - 重定向URI不匹配:Azure门户里的重定向URI要和代码、配置文件里的完全一致,大小写也不能错
- Android登录后无响应:检查
MainActivity的OnActivityResult是否正确传递了参数,还有AndroidManifest.xml里的Intent过滤是否配置对了 - iOS登录后无法返回应用:检查
Info.plist里的URL scheme是否和重定向URI的scheme一致,并且添加了LSApplicationQueriesSchemes配置
内容的提问来源于stack exchange,提问作者Vikram Singh Shekhawat
相关产品推荐
相关产品推荐

