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

基于Yeoman生成的AAD SSO React Teams应用调用同AAD API报CORS错误

核心问题根因

你遇到的报错本质不是CORS配置错误,是API的认证逻辑和前端请求方式不匹配,触发了跨域重定向流程:

  • 你的ASP.NET Core API当前用的是网页浏览器适配的Cookie模式OIDC认证,收到无有效身份的请求时,会返回302状态码,直接把请求重定向到login.microsoftonline.com的授权页
  • 前端的fetch请求属于跨源AJAX调用,碰到跨第三方域名的重定向时,因为微软授权服务器不会返回CORS头,就会被浏览器拦截抛出CORS错误。你在自己API里配的所有CORS规则根本没生效——请求在触发重定向的那一刻就已经离开你的API服务了,根本走不到CORS校验逻辑。
分步解决步骤

1. 调整API的认证模式,改为纯API Bearer认证

删掉适配网页Cookie登录的OIDC重定向逻辑,换成只接受Bearer访问令牌的API认证模式,从根源避免未认证请求被重定向到登录页:

  • 替换Startup.cs里原有的AddAzureAD认证配置,改为API专用的令牌认证逻辑:
    // 替换原来的 services.AddAuthentication(AzureADDefaults.AuthenticationScheme).AddAzureAD(...)
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
    
  • 配置生效后,API收到无有效令牌的请求时,会直接返回401未授权状态码,不再触发302跳转到微软授权页,自然就不会触发第三方域名的CORS拦截。

2. 修正CORS配置,避免逻辑冲突

之前的AllowAnyOrigin()配置存在兼容性问题,调整为和实际前端来源匹配的规则:

services.AddCors(options =>
{
    options.AddPolicy(name: "CorsPolicy",
        builder =>
        {
            // 明确指定你的前端实际来源:ngrok调试地址、Teams嵌入页面域名
            builder.WithOrigins("https://xxxx.eu.ngrok.io", "https://*.teams.microsoft.com")
                .AllowAnyHeader()
                .AllowAnyMethod();
        });
});

注意:app.UseCors("CorsPolicy")的管道顺序必须放在UseAuthentication、UseAuthorization之前,你当前代码的顺序是正确的,不要随意调整位置。

3. 修正前端请求逻辑,正确传递访问令牌

你当前的前端代码存在两个关键问题:拿到了Teams SSO令牌但没有传递给API、调用API时没有带身份凭证:

  • 修改microsoftTeams.authentication.getAuthToken的配置:resources参数必须填写你的API对应的Azure AD应用客户端ID,不能填API的本地/公网地址,否则拿到的令牌无法被API验签
  • 将拿到的访问令牌存入前端状态,调用API时在请求头中携带:
    const [accessToken, setAccessToken] = useState<string>();
    
    // 在getAuthToken的successCallback中,将拿到的token存入状态
    microsoftTeams.authentication.getAuthToken({
        successCallback: (token: string) => {
            setAccessToken(token);
            // 原有解token、设置用户名、通知Teams初始化成功的逻辑保留
        },
        // 其他配置不变
    });
    
    // 调用API时携带Bearer令牌
    fetch("https://你的API公网地址/User", {
        headers: {
            "Authorization": `Bearer ${accessToken}`
        }
    })
        .then(response => response.json())
        .then(data => console.log(data));
    

4. 清理冗余的认证逻辑

你代码中注释掉的ConfigureAuthentication方法里的Cookie、自定义认证方案逻辑不需要保留,纯API场景下不需要/signin-oidc这类网页登录回调端点,保留基础的Bearer认证逻辑即可,避免出现不必要的重定向跳转。


内容的提问来源于stack exchange,提问作者CJ Scholten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 03:36:03