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

托管在Azure的Dot net MVC5应用反复重定向至登录页,重启后才可恢复

故障根因定位

这个低负载正常、高并发突发全用户登录循环、重启恢复的典型表现,核心是用户身份状态持久化失效,结合你给出的代码,常见触发点如下:

  • 会话存储使用默认InProc模式:你当前用SessionTokenStore将会话绑定到当前Web实例的内存中,Azure Web App高并发场景下会触发以下问题:
    • 应用池因内存占用/定时回收规则自动重启,内存内所有会话数据全部清空
    • 多实例负载均衡时用户请求漂移到其他实例,对应实例内存无该用户的会话缓存
    • 高并发下会话存储溢出,旧会话被主动清理
  • ConfidentialClientApplication未使用单例模式:你每次授权码流都新建实例,MSAL的令牌缓存默认绑定实例,高并发下大量重复实例会导致内存泄漏、令牌缓存冲突,最终触发应用池强制回收,全用户状态丢失
  • 下游API调用无容错机制:AuthorizeUserByEmailID调用后端API时如果高并发下出现超时、限流、报错,你当前逻辑直接拦截响应跳转,未做重试或降级,当API可用性波动时会触发大面积重定向

修复方案

1. 替换会话存储为分布式缓存

将默认的内存会话替换为Azure Redis缓存等分布式存储,保证多实例、应用池重启后会话数据不丢失:
首先安装NuGet包:Microsoft.Web.RedisSessionStateProvider,然后在web.config中配置:

<sessionState mode="Custom" customProvider="RedisSessionStateProvider">
  <providers>
    <add name="RedisSessionStateProvider" 
         type="Microsoft.Web.Redis.RedisSessionStateProvider" 
         connectionString="你的Redis连接字符串" 
         throwOnError="false" />
  </providers>
</sessionState>

2. 将ConfidentialClientApplication注册为单例

在Startup中全局初始化一次MSAL客户端,避免重复创建实例:

// 全局静态单例声明
public static IConfidentialClientApplication MsalClient { get; private set; }

// 在Startup.Configuration方法中初始化
var authority = string.Format("https://login.microsoftonline.com/{0}/v2.0", ConfigurationManager.AppSettings["TenantID"]);
MsalClient = ConfidentialClientApplicationBuilder.Create(appId)
    .WithRedirectUri(redirectUri)
    .WithClientSecret(appSecret)
    .WithAuthority(authority)
    .Build();

后续授权逻辑直接复用该静态单例即可,不要每次请求新建。

3. 给下游API调用增加容错逻辑

给AuthorizeUserByEmailID增加重试、超时控制,API异常时优先使用本地已有的身份信息兜底,不要直接跳转登录:

// 示例:增加Polly重试策略
var retryPolicy = Policy.Handle<HttpRequestException>()
    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
authOutput = await retryPolicy.ExecuteAsync(() => methodHelper.AuthorizeUserByEmailID(cachedUser.Email));

4. 验证身份Cookie配置

确认Startup.Auth.cs中Cookie配置适配Azure Web App负载均衡场景,开启Cookie加密适配多实例:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    CookieSecure = CookieSecureOption.Always,
    CookieSameSite = SameSiteMode.Lax,
    SlidingExpiration = true,
    ExpireTimeSpan = TimeSpan.FromHours(8)
});

同时要确保Azure Web App的机器密钥配置为全局统一,不要用自动生成的实例级密钥,避免跨实例Cookie解密失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:45:02