ASP.NET Core 8+Azure AD认证在AWS ECS多任务下无限重定向问题
问题根源
当ECS Fargate运行多个任务实例时,ASP.NET Core默认的内存会话、OIDC状态(state/nonce)缓存无法跨实例共享。用户认证回调请求如果落到和发起认证不同的实例上,该实例找不到对应的state/nonce缓存值,会判定认证验证失败,触发重新认证,进而导致无限重定向循环。你用到的AddInMemoryTokenCaches()确实只负责下游API调用的令牌缓存,和OIDC认证流程的状态缓存无关。
解决方案
核心是把认证流程中需要跨实例共享的状态迁移到分布式存储,AWS环境下优先用ElastiCache Redis(对ASP.NET Core支持最友好),步骤如下:
1. 部署AWS ElastiCache Redis集群
- 在AWS控制台创建ElastiCache Redis集群,确保ECS任务所在的安全组允许访问Redis的默认端口(6379)。
- 记录Redis的连接字符串(格式:
redis-cluster-endpoint:6379)。
2. 配置分布式缓存服务
在Program.cs中添加Redis分布式缓存支持:
// 添加Redis分布式缓存 builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration["Redis:ConnectionString"]; }); // 配置数据保护,让认证相关的加密密钥跨实例共享 var redis = ConnectionMultiplexer.Connect(builder.Configuration["Redis:ConnectionString"]); builder.Services.AddDataProtection() .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
同时在appsettings.json中添加Redis连接配置:
"Redis": { "ConnectionString": "你的Redis集群连接字符串" }
3. 配置分布式会话
替换默认的内存会话为分布式会话,确保用户会话跨实例有效:
// 添加分布式会话服务 builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(30); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; options.Cookie.SameSite = SameSiteMode.Lax; });
注意中间件的顺序,UseSession()必须放在UseAuthentication()之前:
app.UseSession(); app.UseAuthentication(); app.UseAuthorization();
4. 下游API令牌缓存优化(可选)
如果需要下游Microsoft Graph的令牌跨实例共享,把AddInMemoryTokenCaches()替换为分布式令牌缓存:
builder.Services .AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph")) .AddDistributedTokenCaches(); // 替换为分布式缓存
验证
部署修改后的应用到ECS Fargate,调整任务数为2+,发起认证请求,确认不会再出现无限重定向,且认证状态能在不同实例间保持一致。
内容的提问来源于stack exchange,提问作者Dwaragesh Balakrishnan
相关产品推荐
相关产品推荐

