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

Teams命令式Chat Bot的Azure AD SSO Token在Identity Server 4中免登录调用问题

问题分析与解决方案

核心问题根源

当前问题本质是Teams Bot获取的SSO Token无法直接被后端IdentityServer4识别,且后端配置的交互式OIDC流程不匹配Bot的服务端调用场景:

  1. Teams Bot的SSO Token受众(aud)是Bot自身的Client ID,而非后端API或IdentityServer4的资源ID,后端无法验证该Token的有效性。
  2. 后端IdentityServer4配置的ResponseType = "code"属于授权码流程,是交互式认证模式,依赖用户浏览器会话Cookie;但Bot是服务端调用,没有用户浏览器会话,因此添加Prompt="none"会触发AADSTS50058错误(无用户会话Cookie)。

正确实现流程:使用On-Behalf-Of(OBO)流程

要实现Bot携带用户身份调用后端API,需通过Azure AD的On-Behalf-Of流程,将Bot获取的用户SSO Token(用户针对Bot的Token)兑换为针对后端API的访问Token,再用这个Token调用后端API。

步骤1:配置Azure AD权限

  • 在Bot的Azure AD应用注册中,添加后端API的委托权限(如api://{backend-client-id}/access_as_user),并完成管理员同意授权。
  • 在后端API的Azure AD应用注册中,暴露对应的API范围,确保Bot有权限申请该范围的Token。

步骤2:Bot中实现OBO Token兑换

使用Microsoft.Identity.Client库,将用户的SSO Token兑换为后端API的访问Token:

var confidentialClient = ConfidentialClientApplicationBuilder
    .Create("{bot-client-id}")
    .WithClientSecret("{bot-client-secret}")
    .WithAuthority(new Uri($"https://login.microsoftonline.com/{tenant-id}/v2.0"))
    .Build();

// userSsoToken是Teams Bot通过AuthPrompt获取的用户身份Token
var result = await confidentialClient.AcquireTokenOnBehalfOf(
    new[] { "api://{backend-client-id}/access_as_user" }, // 后端API的权限范围
    new UserAssertion(userSsoToken)
).ExecuteAsync();

// 拿到可用于调用后端API的访问Token
var backendApiAccessToken = result.AccessToken;

步骤3:调整后端IdentityServer4配置

后端不需要再走Azure AD的交互式OIDC流程,改为直接验证Azure AD颁发的后端API Token:

方案1:在IdentityServer4中配置Azure AD作为身份源

.AddIdentityServer()
    .AddInMemoryClients(clients)
    .AddInMemoryIdentityResources(identityResources)
    .AddInMemoryApiScopes(apiScopes)
    .AddAzureAdIdentityProvider(options =>
    {
        options.Authority = $"https://login.microsoftonline.com/{tenant-id}/v2.0";
        options.ClientId = "{backend-client-id}";
        options.ClientSecret = "{backend-client-secret}";
        options.Scope = "api://{backend-client-id}/access_as_user";
    });

方案2:直接在API中配置JWT验证

如果后端API不需要通过IdentityServer4中转,可直接验证Azure AD的Token:

.AddJwtBearer("AzureAD", options =>
{
    options.Authority = $"https://login.microsoftonline.com/{tenant-id}/v2.0";
    options.Audience = "api://{backend-client-id}";
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidIssuer = $"https://sts.windows.net/{tenant-id}/",
        ValidateAudience = true,
        ValidAudience = "api://{backend-client-id}",
        ValidateLifetime = true
    };
});

常见误区修正

  • 禁止直接将Bot的SSO Token传递给后端:Token受众不匹配,后端无法通过验证。
  • 后端避免使用授权码流程处理Bot的服务端调用:授权码流程是交互式模式,依赖用户浏览器会话,完全不适合服务端到服务端的用户上下文调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:43:18