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

SharePoint Add-in中JS获取Access Token遇CORS错误求助

解决SharePoint Add-in中调用Azure AD Token端点的CORS问题及令牌生成方案

核心问题分析

  1. Azure AD的令牌端点(accounts.accesscontrol.windows.net)不支持前端跨域请求,所以直接在SharePoint Add-in的JS代码中调用会触发CORS拦截。
  2. 前端代码中直接暴露client_secret是严重的安全风险——任何人都可以通过查看源码获取密钥,进而以你的Add-in身份操作租户资源。

以下是两种可行的解决方案,优先推荐官方原生机制:


方案1:使用SharePoint Add-in内置OAuth令牌机制(推荐)

SharePoint Add-in本身提供了成熟的权限流程,无需手动调用Azure AD端点,自动处理令牌与跨域问题。

方式A:用SP.RequestExecutor自动处理请求(SharePoint托管Add-in首选)

SP.RequestExecutor是微软为SharePoint跨域场景提供的工具,会自动附加合法令牌:

// 替换为你的Add-in Web和宿主Web地址
const appWebUrl = "https://你的Add-in站点地址";
const hostWebUrl = "https://你的SharePoint宿主站点地址";

// 初始化请求执行器
const executor = new SP.RequestExecutor(appWebUrl);

// 调用SharePoint REST API
executor.executeAsync({
  url: `${hostWebUrl}/_api/web`,
  method: "GET",
  headers: { "Accept": "application/json; odata=verbose" },
  success: (response) => {
    const data = JSON.parse(response.body);
    console.log("站点标题:", data.d.Title);
  },
  error: (error) => {
    console.error("请求失败:", error);
  }
});

方式B:手动获取App Only令牌(需自定义请求场景)

如果需要手动持有令牌,可通过SharePoint内置API获取:

const appWebUrl = "https://你的Add-in站点地址";
const hostWebUrl = "https://你的SharePoint宿主站点地址";

const context = new SP.ClientContext(appWebUrl);
const appContextSite = new SP.AppContextSite(context, hostWebUrl);

// 请求App Only令牌
SP.Utilities.Utility.getAppOnlyAccessToken(context, hostWebUrl, appWebUrl).executeQueryAsync(
  (sender, args) => {
    const token = args.get_value();
    console.log("获取到的令牌:", token);
    
    // 用令牌调用SharePoint REST API
    fetch(`${hostWebUrl}/_api/web`, {
      method: "GET",
      headers: {
        "Accept": "application/json; odata=verbose",
        "Authorization": `Bearer ${token}`
      }
    })
    .then(res => res.json())
    .then(data => console.log("站点标题:", data.d.Title))
    .catch(err => console.error("API调用失败:", err));
  },
  (sender, args) => {
    console.error("令牌获取失败:", args.get_message());
  }
);

方案2:通过后端代理获取令牌(强制使用Client Credentials场景)

如果业务必须使用Client Credentials模式,必须通过后端接口中转请求,避免前端暴露密钥和跨域问题:

步骤1:搭建后端代理接口

以Azure Function为例(C#),后端负责请求Azure AD令牌并返回:

[FunctionName("GetSPAccessToken")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
    ILogger log)
{
    // 配置租户及应用信息(建议从环境变量读取,不要硬编码)
    var tenantId = "你的租户ID";
    var clientId = "你的客户端ID@租户ID";
    var clientSecret = "你的客户端密钥";
    var resource = "00000003-0000-0ff1-ce00-000000000000/你的域名@租户ID";

    var tokenEndpoint = $"https://accounts.accesscontrol.windows.net/{tenantId}/tokens/oAuth/2";
    var requestBody = new Dictionary<string, string>
    {
        {"grant_type", "client_credentials"},
        {"client_id", clientId},
        {"client_secret", clientSecret},
        {"resource", resource}
    };

    using (var client = new HttpClient())
    {
        var response = await client.PostAsync(tokenEndpoint, new FormUrlEncodedContent(requestBody));
        var tokenData = await response.Content.ReadFromJsonAsync<TokenResponse>();
        return new OkObjectResult(tokenData.access_token);
    }
}

// 定义令牌响应模型
public class TokenResponse
{
    public string access_token { get; set; }
}

步骤2:前端调用后端接口获取令牌

// 替换为你的后端接口地址
const proxyEndpoint = "https://你的Azure Function地址/api/GetSPAccessToken";

fetch(proxyEndpoint, { method: "POST" })
.then(response => response.text())
.then(token => {
    // 调用SharePoint REST API
    return fetch("https://你的SharePoint站点/_api/web", {
        method: "GET",
        headers: {
            "Accept": "application/json; odata=verbose",
            "Authorization": `Bearer ${token}`
        }
    });
})
.then(res => res.json())
.then(data => console.log("站点标题:", data.d.Title))
.catch(error => console.error("请求失败:", error));

关键注意事项

  • 禁止在前端代码中硬编码client_secret,避免敏感信息泄露。
  • 优先使用SharePoint Add-in原生权限机制,这是微软官方推荐的安全方案。
  • 后端代理接口需添加权限验证(比如限制请求来源为你的Add-in域名),防止恶意调用。

内容的提问来源于stack exchange,提问作者Sayan Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:37:47