如何将msalcache.bin存储的凭证转换为Azure.Core TokenCredential
自定义MSAL缓存凭证实现方案
可以通过继承Azure SDK的TokenCredential抽象类,自定义实现读取本地MSAL缓存的凭证类,具体实现方式如下:
前置依赖
项目需提前安装两个NuGet包:
Microsoft.Identity.ClientMicrosoft.Identity.Client.Extensions.MsalAzure.Core
自定义凭证类实现
using Azure.Core; using Microsoft.Identity.Client; using Microsoft.Identity.Client.Extensions.Msal; public class MsalCacheCredential : TokenCredential { private readonly IPublicClientApplication _msalApp; /// <param name="clientId">生成MSAL缓存时使用的应用ClientId,必须和生成缓存的配置完全一致</param> /// <param name="msalCacheDirectory">MSAL缓存文件所在目录</param> /// <param name="cacheFileName">MSAL缓存文件名,默认和生成逻辑保持一致为.msalcache.bin</param> /// <param name="tenantId">租户ID,单租户应用需要传入,多租户/个人账号场景默认填common即可</param> public MsalCacheCredential(string clientId, string msalCacheDirectory, string cacheFileName = ".msalcache.bin", string tenantId = "common") { // 构造和生成缓存时配置完全一致的MSAL客户端 _msalApp = PublicClientApplicationBuilder .Create(clientId) .WithAuthority(AzureCloudInstance.AzurePublic, tenantId) .Build(); // 绑定本地已存在的缓存文件 var storageProperties = new StorageCreationPropertiesBuilder( cacheFileName, msalCacheDirectory) .Build(); // 加载本地缓存 var cacheHelper = MsalCacheHelper.CreateAsync(storageProperties).GetAwaiter().GetResult(); cacheHelper.VerifyPersistence(); cacheHelper.RegisterCache(_msalApp.UserTokenCache); } public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) { return GetTokenAsync(requestContext, cancellationToken).GetAwaiter().GetResult(); } public override async ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken) { // 读取缓存中的账户信息 var accounts = await _msalApp.GetAccountsAsync(); var targetAccount = accounts.FirstOrDefault(); if (targetAccount == null) { throw new CredentialUnavailableException("MSAL缓存中无有效账户信息"); } try { // 静默从缓存获取对应scope的Token var authResult = await _msalApp.AcquireTokenSilent(requestContext.Scopes, targetAccount) .ExecuteAsync(cancellationToken); return new AccessToken(authResult.AccessToken, authResult.ExpiresOn); } catch (MsalUiRequiredException) { // 缓存失效、没有对应scope权限时抛出凭证不可用异常,ChainedTokenCredential会自动切换下一个凭证 throw new CredentialUnavailableException("MSAL缓存凭证已失效,需要重新登录"); } } }
使用方式
和你预期的写法完全一致,直接注入到ChainedTokenCredential即可:
var client = new SecretClient(vault, new ChainedTokenCredential( new ManagedIdentityCredential(), new MsalCacheCredential(_config.ClientId, _directory, ".msalcache.bin") ));
注意事项
- 自定义凭证的ClientId、租户ID、云环境配置必须和生成MSAL缓存的配置完全一致,否则无法读取缓存中的凭证
- 如果本地缓存是系统级加密存储的,
MsalCacheHelper会自动处理解密逻辑,不需要额外开发 - 凭证不可用的异常会被
ChainedTokenCredential自动捕获,不会影响链上其他凭证的正常使用
内容的提问来源于stack exchange,提问作者NeilMacMullen
相关产品推荐
相关产品推荐

