You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:05:19