Xamarin.iOS平台使用Azure.Identity初始化UsernamePasswordCredential抛未实现异常
问题根因
该报错的核心原因是Xamarin.iOS依赖的Mono运行时未实现System.Diagnostics.Tracing.EventSource.GetSources()方法,而当前使用的Azure.Core版本(由Azure.Identity 1.4.1依赖引入)在初始化内部日志组件时调用了这个未实现的API,因此抛出未实现异常。相同代码在.NET 5控制台中可以正常运行,是因为.NET 5+的完整运行时已经实现了该API。
解决方案
方案1:添加兼容开关绕过日志依赖(操作最简单,优先尝试)
在初始化UsernamePasswordCredential实例前,添加一行代码禁用Azure.Core的EventSource日志功能,绕开对未实现API的调用:
AppContext.SetSwitch("Azure.Core.DisableEventSource", true);
修改后的GraphService.Init方法参考:
public void Init(string username, string password, string tenantId, string clientId, string eventKeyword) { this._eventKeyword = eventKeyword; Console.WriteLine("Creo credentials provider"); // 新增以下兼容开关 AppContext.SetSwitch("Azure.Core.DisableEventSource", true); var userNamePasswordCredential = new UsernamePasswordCredential( username, password, tenantId, clientId, new TokenCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }); Console.WriteLine("Creo graph service client"); this._graphClient = new GraphServiceClient(userNamePasswordCredential); }
该开关是Azure SDK官方提供的兼容配置,仅关闭内部EventSource日志输出,不会影响认证、接口调用等核心功能。
方案2:调整NuGet包到兼容版本
如果方案1未生效,可以尝试降级包到已知兼容的版本组合:
- 将Azure.Identity降级到1.3.0版本,该版本依赖的Azure.Core不会调用
GetSources()方法,注意同步调整Microsoft.Graph的版本到匹配范围。
方案3:使用原生MSAL库实现认证
如果上述方案都不符合需求,可以放弃Azure.Identity的封装,直接使用微软身份验证库(MSAL)获取访问令牌,再手动构造Graph客户端,MSAL原生兼容Xamarin平台,不会出现运行时API缺失问题:
// 用MSAL通过用户名密码获取令牌 var pca = PublicClientApplicationBuilder .Create(clientId) .WithTenantId(tenantId) .Build(); var authResult = await pca.AcquireTokenByUsernamePassword(new[] { "User.Read" }, username, password) .ExecuteAsync(); // 用令牌构造GraphServiceClient this._graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(request => { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken); return Task.CompletedTask; }));
内容的提问来源于stack exchange,提问作者Gaburiere
相关产品推荐
相关产品推荐

