React前端从Azure AD获取API应用Bearer令牌遇跨域问题
解决React SPA获取Azure AD API令牌的跨域问题
你的核心问题是手动调用Azure AD的authorize和token接口会触发浏览器跨域拦截——这些接口本身不支持CORS,浏览器的同源策略会阻止你读取响应,这是设计使然。MSAL.js已经封装了所有授权流程,完全不需要你手动发送这些请求。
正确的实现步骤
1. 配置Azure AD应用权限
- 登录Azure门户,找到你的前端SPA应用注册
- 进入「API权限」页面,点击「添加权限」→「我的 APIs」,选择你的ASP.NET Web API应用
- 添加委托权限(因为是前端用户触发的请求),添加完成后点击「授予管理员同意」(如果是租户内应用需要全局生效)
2. 使用MSAL.js获取API专用令牌
不需要手动调用token接口,直接用MSAL提供的acquireTokenSilent或acquireTokenPopup方法,指定API的作用域即可获取针对该API的Bearer令牌。
代码示例
首先定义API的作用域(替换为你的API应用ID和实际作用域):
// API作用域格式:api://{API应用ID}/{权限名称} const apiScopes = ["api://YOUR-API-APP-ID/access_as_user"];
在React组件中获取令牌并调用API:
import { useMsal } from "@azure/msal-react"; function App() { const { instance, accounts } = useMsal(); // 获取API令牌 const getApiToken = async () => { try { // 优先静默获取令牌(用户已登录时无需弹窗) const response = await instance.acquireTokenSilent({ account: accounts[0], scopes: apiScopes, }); return response.accessToken; } catch (err) { // 静默失败时,弹出授权窗口 const response = await instance.acquireTokenPopup({ scopes: apiScopes, }); return response.accessToken; } }; // 调用API并携带令牌 const callProtectedApi = async () => { const token = await getApiToken(); const apiResponse = await fetch("https://your-api-domain/api/values", { method: "GET", headers: { Authorization: `Bearer ${token}`, }, }); const data = await apiResponse.json(); console.log("API返回数据:", data); }; return ( <div> <button onClick={callProtectedApi}>调用受保护API</button> </div> ); } export default App;
3. 补充API端配置(ASP.NET Web API)
确保你的API已配置Azure AD认证,验证前端传来的Bearer令牌:
// Program.cs using Microsoft.Identity.Web; var builder = WebApplication.CreateBuilder(args); // 添加Azure AD认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")); builder.Services.AddAuthorization(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
为什么之前的方法不行?
- 浏览器同源策略限制:Azure AD的
/authorize和/token接口没有配置允许你的前端域名的CORS响应头,浏览器会拦截跨域请求的响应 - Postman/Swagger不受限制:这些工具不属于浏览器环境,不遵循同源策略,所以可以直接调用接口
- MSAL的正确流程:MSAL.js通过重定向或弹出窗口的方式完成授权,这种方式绕过了CORS限制——授权流程在Azure AD的域名下完成,令牌会通过安全的方式返回给前端应用
内容的提问来源于stack exchange,提问作者J_Developer
相关产品推荐
相关产品推荐

