Azure AD B2C+ASP.NET MVC+JQuery Ajax:Ajax刷新过期令牌遇跨域问题
解决方案:将Azure AD B2C认证的AJAX 302重定向改为401响应
你的思路完全正确
AJAX请求不会自动跟随302重定向,且Azure AD B2C域名未配置允许你的应用域名的CORS规则,因此必然触发跨域错误。将令牌过期时的302重定向替换为401未授权响应,再由前端AJAX捕获后引导用户登录,是标准且可行的解决方案。
实现步骤(中间件层面拦截重定向)
身份验证中间件的重定向逻辑(如OnRedirectToLogin)执行早于控制器的[Authorize]属性,因此需要在OpenIdConnect中间件的事件中处理:
1. 配置OpenIdConnect事件拦截重定向
在Program.cs中,修改Azure AD B2C的身份验证配置,添加OnRedirectToLogin事件处理代码:
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options => { options.Events.OnRedirectToLogin = context => { // 判断是否为AJAX请求:检查X-Requested-With头或Accept头 bool isAjaxRequest = context.Request.Headers.ContainsKey("X-Requested-With") && context.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; bool acceptsJson = context.Request.Headers.Accept.ToString().IndexOf("application/json", StringComparison.OrdinalIgnoreCase) >= 0; if (isAjaxRequest || acceptsJson) { // 返回401未授权响应,附带自定义JSON信息 context.Response.StatusCode = StatusCodes.Status401Unauthorized; context.Response.ContentType = "application/json"; return context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(new { Error = "Unauthorized", Message = "登录已过期,请重新登录" })); } // 非AJAX请求保持默认的重定向登录行为 context.Response.Redirect(context.RedirectUri); return Task.CompletedTask; }; });
2. 前端AJAX捕获401并处理
使用jQuery全局AJAX错误处理器,捕获401响应后引导用户跳转至登录页:
$(document).ajaxError(function(event, xhr) { if (xhr.status === 401) { // 跳转到应用登录路由,由Identity自动重定向到Azure AD B2C认证页 window.location.href = "/Account/Login"; } });
额外注意事项
- jQuery默认会给AJAX请求添加
X-Requested-With: XMLHttpRequest头,若手动编写AJAX请求需确保带上该头 - 若控制器返回JSON格式数据,确保请求的
Accept头包含application/json,以便中间件正确识别AJAX请求 - 不要尝试配置CORS允许
b2clogin.com,既不安全也无法解决跨域问题(重定向后的请求由浏览器自动发起,不会携带CORS相关头)
内容的提问来源于stack exchange,提问作者Dazfl
相关产品推荐
相关产品推荐

