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

.NET 8/C#12中用户分配托管身份认证Azure Redis缓存的自动续期问题

用用户分配托管身份自动认证Azure Redis Cache(.NET 8/C# 12)

核心思路

要实现自动认证,需完成两个关键环节:

  1. 通过Azure Identity库获取带过期时间的Entra令牌
  2. 在令牌过期前主动刷新并重新执行Redis AUTH命令

1. 获取Entra令牌及过期时间

使用Azure.Identity库的ManagedIdentityCredential(针对用户分配托管身份)获取令牌,令牌对象的ExpiresOn属性直接提供过期时间。需要指定托管身份的Client ID,以及Redis专属的令牌范围https://redis.azure.com/.default。

2. 自动刷新Redis AUTH的实现

用后台定时任务(如Timer)定期检查令牌状态,在过期前10分钟左右刷新令牌,然后调用Redis的AUTH命令更新认证信息。主动刷新比依赖连接失败事件兜底更可靠。

完整代码示例

先安装必要的NuGet包:

Install-Package Azure.Identity
Install-Package StackExchange.Redis
using Azure.Identity;
using StackExchange.Redis;
using System.Timers;

namespace RedisManagedIdentityAuth
{
    public class RedisAuthManager
    {
        private readonly ConnectionMultiplexer _redisMultiplexer;
        private readonly string _managedIdentityObjectId; // 托管身份的对象ID
        private readonly string _managedIdentityClientId; // 用户分配托管身份的Client ID
        private readonly Timer _refreshTimer;
        private AccessToken _currentToken;

        public RedisAuthManager(string redisConnectionString, string managedIdentityObjectId, string managedIdentityClientId)
        {
            _managedIdentityObjectId = managedIdentityObjectId;
            _managedIdentityClientId = managedIdentityClientId;

            // 初始化Redis连接(仅基础连接,不含认证信息)
            _redisMultiplexer = ConnectionMultiplexer.Connect(redisConnectionString);

            // 每5分钟检查一次令牌状态
            _refreshTimer = new Timer(5 * 60 * 1000);
            _refreshTimer.Elapsed += RefreshTokenAndAuth;
            _refreshTimer.AutoReset = true;

            // 首次启动时完成认证
            RefreshTokenAndAuth(null, null);
        }

        private async void RefreshTokenAndAuth(object sender, ElapsedEventArgs e)
        {
            try
            {
                // 令牌剩余有效期大于10分钟则跳过刷新
                if (_currentToken.ExpiresOn > DateTimeOffset.UtcNow.AddMinutes(10))
                {
                    return;
                }

                // 获取新的Entra令牌
                var credential = new ManagedIdentityCredential(_managedIdentityClientId);
                _currentToken = await credential.GetTokenAsync(new Azure.Core.TokenRequestContext(
                    new[] { "https://redis.azure.com/.default" }));

                // 执行Redis AUTH命令完成认证
                var server = _redisMultiplexer.GetServer(_redisMultiplexer.GetEndPoints().First());
                server.Execute("AUTH", _managedIdentityObjectId, _currentToken.Token);

                Console.WriteLine($"Redis认证刷新成功,新令牌过期时间:{_currentToken.ExpiresOn:yyyy-MM-dd HH:mm:ss}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"刷新Redis认证失败:{ex.Message}");
                // 可添加重试逻辑,比如间隔30秒后重试
            }
        }

        // 暴露Redis数据库实例供业务代码调用
        public IDatabase GetDatabase(int db = 0)
        {
            return _redisMultiplexer.GetDatabase(db);
        }
    }

    // 使用示例
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var redisConnectionString = "your-redis-cache.redis.cache.windows.net:6380,ssl=True";
            var managedIdentityObjectId = "your-managed-identity-object-id";
            var managedIdentityClientId = "your-user-assigned-managed-identity-client-id";

            var authManager = new RedisAuthManager(redisConnectionString, managedIdentityObjectId, managedIdentityClientId);
            var db = authManager.GetDatabase();

            // 测试Redis读写
            await db.StringSetAsync("test-key", "test-value", TimeSpan.FromMinutes(30));
            var value = await db.StringGetAsync("test-key");
            Console.WriteLine($"Redis取值:{value}");

            // 保持程序运行
            Console.ReadLine();
        }
    }
}

关键注意事项

  • 权限配置:确保用户分配托管身份被授予Azure Redis Cache的Redis Cache Contributor角色,或包含Microsoft.Cache/redisCache/keys/*权限的自定义角色。
  • 令牌范围:必须使用https://redis.azure.com/.default作为令牌请求范围,否则获取的令牌无法通过Redis认证。
  • 刷新时机:设置在令牌过期前10-15分钟刷新,避免网络延迟等问题导致令牌过期后才触发刷新。
  • 错误处理:添加重试逻辑处理令牌获取失败或Redis认证失败的场景,提升系统可用性。

内容的提问来源于stack exchange,提问作者santosh kumar patro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:47:33