ASP.NET Core MVC+VueJS SPA集成Azure AD认证:会话过期重定向问题
解决方案
问题根源
你遇到的CORS错误,本质是AJAX请求无法处理跨域重定向:当会话过期后,ASP.NET Core默认会返回302重定向到Azure AD登录页,但前端axios的跨域请求会被浏览器拦截,触发CORS错误。你之前修改OnRedirectToIdentityProvider无效,是因为重定向逻辑最先由Cookie认证中间件触发,而非OpenIdConnect中间件。
方案1:让API请求返回401(推荐)
针对AJAX请求返回401状态码,而非重定向,前端可通过拦截器统一处理跳转;非页面请求(如浏览器直接访问)仍保持重定向到自定义登录页。
修改Program.cs配置
在Cookie认证中间件的事件中添加判断逻辑:
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(options => { builder.Configuration.Bind("AzureAd", options); options.Events = new OpenIdConnectEvents { OnTokenValidated = context => { // 保留你原有的UserID Claim添加逻辑 string query = "select dbo.A2F_0013_ReturnUserIDForEmail(@Email) as UserID"; string connectionString = builder.Configuration.GetValue<string>("ConnectionStrings:DBContext"); string signInEmailAddress = context.Principal.FindFirstValue("preferred_username"); using (var connection = new SqlConnection(connectionString)) { var queryResult = connection.QueryFirst(query, new { Email = signInEmailAddress }); var claims = new List<Claim> { new Claim("UserID", queryResult.UserID.ToString()) }; var appIdentity = new ClaimsIdentity(claims); context.Principal.AddIdentity(appIdentity); } return Task.CompletedTask; }, }; }) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(builder.Configuration.GetSection("DownstreamApi")) .AddInMemoryTokenCaches() // 配置Cookie认证的重定向逻辑 .AddCookie(options => { options.Events.OnRedirectToLogin = context => { // 判断是否为AJAX请求(可根据你的前端实际情况调整判断条件) bool isAjaxRequest = context.Request.Headers["X-Requested-With"] == "XMLHttpRequest" || context.Request.ContentType?.StartsWith("application/json") == true || context.Request.Headers["Accept"]?.Contains("application/json") == true; if (isAjaxRequest) { // 返回401及自定义提示信息 context.Response.StatusCode = StatusCodes.Status401Unauthorized; context.Response.ContentType = "application/json"; var errorMsg = JsonSerializer.Serialize(new { message = "登录已过期,请重新登录" }); return context.Response.WriteAsync(errorMsg); } // 非AJAX请求,重定向到自定义登录页 context.Response.Redirect("/Login"); return Task.CompletedTask; }; });
前端axios拦截器处理
在Vue项目中添加axios响应拦截器,捕获401状态码并跳转到自定义登录页:
axios.interceptors.response.use( response => response, error => { if (error.response?.status === 401) { window.location.href = '/Login'; } return Promise.reject(error); } );
方案2:统一重定向到自定义登录页
如果希望所有未认证请求都重定向到你的localhost/login页面(而非Azure AD直接登录页),只需确保自定义登录页包含Azure AD登录按钮,并调整Cookie认证的LoginPath:
1. 配置Cookie的LoginPath
在上述AddCookie配置中,直接设置LoginPath:
.AddCookie(options => { options.LoginPath = "/Login"; // 指向你的自定义登录页 // 保留OnRedirectToLogin的AJAX判断逻辑(可选) });
2. 自定义登录页添加Azure AD登录按钮
在/Login页面的Razor视图中,添加Microsoft Identity的登录组件:
@page @{ ViewData["Title"] = "登录"; } <div class="login-container"> <h1>请登录</h1> <a asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn" class="btn btn-primary"> 使用Azure AD登录 </a> </div>
关于CORS的说明
不需要配置CORS允许login.microsoft.com,这属于不良实践:重定向是浏览器端的跳转行为,不属于AJAX跨域请求范畴,配置CORS无法解决该问题,反而会引入不必要的安全风险。
内容的提问来源于stack exchange,提问作者Qiuzman
相关产品推荐
相关产品推荐

