Vue.js前端与.NET 5后端集成Azure AD认证跨域问题求助
问题分析
跨域拦截的核心原因是:Vue作为SPA前端发起的是跨域AJAX请求,当后端[Authorize]触发重定向到Azure AD登录页时,浏览器会因跨域安全策略拦截该重定向——重定向目标(Azure AD域名)不在前端CORS允许列表内,且AJAX请求的重定向不符合跨域规范。
原MVC模式是服务器端渲染,重定向是服务器直接返回给浏览器的页面跳转,不属于AJAX跨域请求,因此无问题,但SPA场景逻辑完全不同。
解决方案
1. 后端调整:切换到Bearer Token认证模式
后端需从「服务器端重定向登录」改为「验证前端传来的Azure AD Token」,不再主动重定向,而是返回401让前端处理登录逻辑。
修改Startup.cs:
public void ConfigureServices(IServiceCollection services) { // 配置CORS,允许前端域名、携带凭证、必要请求头 services.AddCors(options => { options.AddPolicy("VueCorsPolicy", policy => { policy.WithOrigins("http://localhost:8080") // 替换为你的Vue前端实际域名 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); services.AddHttpClient(); services.AddMemoryCache(); // 配置Azure AD Bearer认证,用于验证前端传来的Token services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(_configuration.GetSection("AzureAd")); services.AddAuthorization(options => { options.AddPolicy("AuthorizeAccess", policy => policy.Requirements.Add(new Helpside.Domain.Attributes.AuthorizeAccessAttribute())); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 其他中间件... // CORS中间件需放在UseRouting和UseAuthorization之间 app.UseCors("VueCorsPolicy"); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); // 其他中间件... }
测试Controller保持[Authorize]即可,现在会验证Bearer Token,未授权时返回401:
[Authorize] [HttpGet("Test")] public JsonResult Test() { var response = "Test"; return Json(response); }
2. 前端调整:用MSAL.js直接完成Azure AD登录
前端使用微软msal.js库(MSAL v2)完成登录,获取Access Token后,请求后端API时携带Token:
步骤1:安装MSAL.js
npm install @azure/msal-browser
步骤2:初始化MSAL并实现登录逻辑
在Vue项目中创建auth.js:
import { PublicClientApplication } from '@azure/msal-browser'; const msalConfig = { auth: { clientId: "你的Azure AD应用ClientId", authority: "https://login.microsoftonline.com/你的租户ID", redirectUri: "http://localhost:8080" // Vue前端回调地址,需在Azure AD应用中配置 } }; const msalInstance = new PublicClientApplication(msalConfig); // 弹窗登录方法 export const login = async () => { const loginRequest = { scopes: ["api://你的后端API应用ID/access_as_user"] // 后端API的权限范围,需在Azure AD中配置 }; await msalInstance.loginPopup(loginRequest); }; // 静默获取Access Token export const getAccessToken = async () => { const account = msalInstance.getAllAccounts()[0]; if (!account) throw new Error("用户未登录"); const tokenRequest = { scopes: ["api://你的后端API应用ID/access_as_user"], account: account }; const response = await msalInstance.acquireTokenSilent(tokenRequest); return response.accessToken; };
步骤3:请求后端API时自动携带Token
在Vue组件或axios拦截器中添加Token逻辑:
import axios from 'axios'; import { getAccessToken, login } from './auth'; // 创建axios实例 const api = axios.create({ baseURL: "http://你的后端API域名" }); // 请求拦截器,自动注入Token api.interceptors.request.use(async (config) => { const token = await getAccessToken(); config.headers.Authorization = `Bearer ${token}`; return config; }, (error) => { return Promise.reject(error); }); // API调用示例 async function callTestApi() { try { const response = await api.get('/Test'); console.log(response.data); } catch (error) { // 处理401未授权,引导用户登录 if (error.response?.status === 401) { await login(); // 登录后重新请求 const response = await api.get('/Test'); console.log(response.data); } } }
3. Azure AD应用配置要点
- 前端SPA应用:在Azure AD中注册SPA应用,添加前端域名作为重定向URI,启用PKCE模式。
- 后端API应用:在Azure AD中注册API应用,暴露API权限(如
access_as_user),并将前端SPA应用添加为授权客户端。 - 后端
appsettings.json的AzureAd配置需指向后端API应用信息:
"AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "你的租户域名", "TenantId": "你的租户ID", "ClientId": "后端API应用的ClientId", "Audience": "api://后端API应用的ClientId" }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

