You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将msalcache.bin存储的凭证转换为Azure.Core TokenCredential

自定义MSAL缓存凭证实现方案

可以通过继承Azure SDK的TokenCredential抽象类,自定义实现读取本地MSAL缓存的凭证类,具体实现方式如下:

前置依赖

项目需提前安装两个NuGet包:

  • Microsoft.Identity.Client
  • Microsoft.Identity.Client.Extensions.Msal
  • Azure.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:36:04