.NET 6.0中Ajax调用时会话超时重定向问题
解决Azure AD认证会话超时后Ajax调用的CORS问题
问题根源
会话超时后,后端默认会返回302重定向到Azure AD登录页,但Ajax请求属于跨域场景(login.microsoftonline.com与你的应用域名不同),浏览器会拦截跨域重定向,导致CORS错误,前端无法感知到认证状态变化。
解决方案
1. 后端配置:让未授权的Ajax请求返回401而非302
修改Program.cs中的认证配置,添加Cookie认证事件,判断请求是否为Ajax,若是则直接返回401状态码,避免触发跨域重定向:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .AddCookie(options => { options.Events.OnRedirectToLogin = context => { // 判断是否为Ajax请求(通过请求头标识) if (context.Request.Headers["X-Requested-With"] == "XMLHttpRequest" || context.Request.Headers["Accept"].Contains("application/json")) { context.Response.StatusCode = StatusCodes.Status401Unauthorized; return Task.CompletedTask; } // 非Ajax请求正常重定向到登录页 context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; }; // 匹配IIS应用池的20分钟超时配置 options.ExpireTimeSpan = TimeSpan.FromMinutes(20); options.SlidingExpiration = true; // 活跃操作时自动延长会话 }); builder.Services.AddAuthorization(options => { options.AddPolicy("ReadWrite", policyBuilder => policyBuilder.RequireClaim("groups", builder.Configuration.GetValue<string>("AuthorizedGroups:mygroupname"))); });
2. 前端全局捕获401错误,处理认证跳转或超时提示
在前端代码中添加全局Ajax拦截器,捕获401状态码后,触发登录跳转或显示超时提示:
示例(Axios拦截器)
axios.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { // 跳转到应用登录页,会自动重定向到Azure AD完成认证 window.location.href = "/Account/Login"; // 若需要显示自定义提示,可替换为弹窗逻辑 // document.getElementById("timeout-modal").style.display = "block"; } return Promise.reject(error); } );
示例(jQuery全局配置)
$.ajaxSetup({ complete: function(xhr) { if (xhr.status === 401) { window.location.href = "/Account/Login"; } } });
3. 验证要点
- 确保前端Ajax请求自动携带
X-Requested-With: XMLHttpRequest请求头(主流前端框架如jQuery、Axios默认会添加) - 测试会话超时后发起Ajax请求,此时后端返回401,前端可正常触发跳转或提示,不会出现CORS错误
内容的提问来源于stack exchange,提问作者san
相关产品推荐
相关产品推荐

