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

.NET MAUI中使用MSAL:如何避免重启已登录应用后需UI获取访问令牌

Windows 11平台MAUI应用MSAL令牌缓存重启丢失的解决方法

问题核心是:Windows平台MAUI应用默认使用内存级令牌缓存,重启应用后缓存会被清空;而Android平台MSAL有默认的持久化缓存实现,所以无此问题。以下是具体解决步骤:

1. 实现自定义令牌缓存持久化

通过将MSAL令牌缓存序列化到应用私有本地文件,实现重启后缓存保留。

步骤1:编写缓存序列化助手类

public static class TokenCacheHelper
{
    // 缓存文件存储路径(Windows应用私有目录)
    private static readonly string _cacheFilePath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "msal_token_cache.bin");

    // 配置缓存序列化回调
    public static void EnableSerialization(ITokenCache tokenCache)
    {
        tokenCache.SetBeforeAccess(BeforeAccessNotification);
        tokenCache.SetAfterAccess(AfterAccessNotification);
    }

    // 读取缓存文件并反序列化
    private static void BeforeAccessNotification(TokenCacheNotificationArgs args)
    {
        if (File.Exists(_cacheFilePath))
        {
            args.TokenCache.DeserializeMsalV3(File.ReadAllBytes(_cacheFilePath));
        }
    }

    // 缓存变更后写入文件
    private static void AfterAccessNotification(TokenCacheNotificationArgs args)
    {
        if (args.HasStateChanged)
        {
            File.WriteAllBytes(_cacheFilePath, args.TokenCache.SerializeMsalV3());
        }
    }
}

步骤2:初始化PublicClientApplication时绑定缓存

var pca = PublicClientApplicationBuilder
    .Create("你的客户端ID")
    .WithRedirectUri("msal-你的客户端ID://auth")
    .Build();

// 启用自定义缓存序列化
TokenCacheHelper.EnableSerialization(pca.UserTokenCache);

2. 可选:加密缓存文件(增强安全性)

令牌包含敏感信息,可使用Windows数据保护API加密缓存文件:

public static class TokenCacheHelper
{
    private static readonly string _cacheFilePath = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        "msal_token_cache.bin");
    private static readonly DataProtectionProvider _dataProtector = new DataProtectionProvider();

    public static void EnableSerialization(ITokenCache tokenCache)
    {
        tokenCache.SetBeforeAccess(BeforeAccessNotification);
        tokenCache.SetAfterAccess(AfterAccessNotification);
    }

    private static void BeforeAccessNotification(TokenCacheNotificationArgs args)
    {
        if (File.Exists(_cacheFilePath))
        {
            using var fileStream = new FileStream(_cacheFilePath, FileMode.Open);
            using var protectedStream = _dataProtector.UnprotectStream(fileStream);
            var encryptedBytes = new byte[protectedStream.Length];
            protectedStream.Read(encryptedBytes, 0, encryptedBytes.Length);
            args.TokenCache.DeserializeMsalV3(encryptedBytes);
        }
    }

    private static void AfterAccessNotification(TokenCacheNotificationArgs args)
    {
        if (args.HasStateChanged)
        {
            using var fileStream = new FileStream(_cacheFilePath, FileMode.Create);
            using var protectedStream = _dataProtector.ProtectStream(fileStream);
            var cacheBytes = args.TokenCache.SerializeMsalV3();
            protectedStream.Write(cacheBytes, 0, cacheBytes.Length);
        }
    }
}

3. 额外检查点

  • 确保使用最新稳定版的Microsoft.Identity.Client包,旧版本可能存在Windows平台缓存处理bug。
  • Windows应用无需额外权限,LocalApplicationData是应用私有目录,默认允许读写。

内容的提问来源于stack exchange,提问作者Ignotus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:10:49