Papa Labs

想让总部通讯录同步到子公司,配的却是错误的功能——Cross-Tenant Sync 和 Shared Channel 是两回事

总部租户有两百多个活跃邮箱,且新人入职频繁。这次的目标很朴素:让子公司租户的用户能实时搜索到总部的通讯录条目(姓名、邮箱),不需要每次手动维护联系人

按微软官方文档,这个需求对应的功能叫 Cross-Tenant Synchronization(跨租户同步)——于是照着配了一整套:在子公司租户(目标租户)配置 Inbound Access 允许总部租户同步进来、勾上”自动兑现邀请”的信任设置;在总部租户(源租户)配置 Outbound Access,指定要同步的用户/组范围。这一步需要 Microsoft Entra ID P1 或 P2 授权——好在当时公司的 Business Premium 套餐已经默认带了 P1,不需要额外采购。

配置完成,选一个用户做”按需预配(Provision on demand)“测试——同步成功,用户确实出现在了子公司租户里

同步”成功”了,体验却是灾难

问题出在 Teams。同步过去的用户,从总部这一侧的 Teams 界面看,依然被标记为”外部人员(External)“;从子公司那一侧发起对话,虽然不再显示”External”标签,但用户状态永远显示”离线(Offline)“,即便对方分明在线

这不是小瑕疵。日常协作里,“看起来在线却显示离线”会直接误导对方”这个人不在""消息不会被看到”,从而选择改用其他渠道——这是一个足以让整个方案作废的体验缺陷,评估结论直接写成”这套同步完全不可用”,把测试用户删除,项目搁置。

几个月后重新捡起来,才发现问题问错了方向

后来因为子公司同事真的需要和总部人员建立共享频道(Shared Channel)协作,重新翻这个问题——这次得到的关键提示是:

之前配置的是 B2B Collaboration(传统的访客协作模式)的信任设置,而 Teams 共享频道真正依赖的是另一套独立协议——B2B Direct Connect。 两者都挂在”跨租户访问设置”这同一个界面下,长得像同一件事,实际上是完全不同的两条通路:

  • B2B Collaboration / Cross-Tenant Sync:把对方的身份”引入”到本租户,生成一个客体对象——正是这一步的语义错位,导致 Teams 界面把同步进来的用户当作”访客”而非”原生在场用户”,于是有了那个诡异的离线状态;
  • B2B Direct Connect:不创建任何客体对象,双方用户始终留在各自的租户里,凭 Entra ID 之间的信任桥直接互通——这才是共享频道设计时假设的模型。

正确的配置:两个租户,各自双向打开 B2B Direct Connect

修复过程是把之前配置里被忽略的那个页签重新走一遍——关键是在”跨租户访问设置”里,不要停留在默认打开的 B2B Collaboration 页签,而要切到 B2B Direct Connect 页签:

  • 总部租户:Inbound access 和 Outbound access,都切到 B2B Direct Connect 页签,选择 Customize settings,对外部用户和应用都设为 Allow access;
  • 子公司租户:同样对 Inbound 和 Outbound 各自确认 B2B Direct Connect 页签下是 Allow access。

两边、两个方向,一共四处都要确认,少一处都不通。

信任桥搭好后还有一层容易漏掉的开关:Teams 管理中心的策略,在 Teams policies 里找到”共享频道”分组,把三个开关全部打开——创建共享频道、邀请外部用户加入共享频道、加入外部共享频道。

等待:B2B Direct Connect 的同步不是即时的

配置全部确认无误后,不要立刻找同事测试。Entra ID 的跨租户信任设置在微软全球服务器间同步通常需要 2 到 6 小时,过早测试大概率还会撞见同样的报错,白白制造”是不是又没配对”的怀疑。

先用一个内部小范围的测试频道做验证,而不是直接上生产频道——这样即便信任还没同步完成,也不会干扰真正要用的团队。同步完成的判断标准也很干净利落:

  • 零客体对象检查:去总部 Entra ID 的 Users 列表里找子公司的账号——如果配置正确,根本不会出现,因为 B2B Direct Connect 不创建访客对象,目录保持干净;
  • 体验检查:子公司用户打开 Teams,能在标准频道列表里看到共享频道,旁边带一个链接图标,不需要切换租户;
  • 审计日志检查:Entra ID 审计日志里能看到一条”更新跨租户访问策略”的事件,确认改动范围精确落在 B2B Direct Connect 参数上,没有牵动其他安全策略。

两条完全不同的通路:Cross-Tenant Sync / B2B Collaboration 会把对方引入本租户当作访客对象,Teams 因此显示离线;共享频道真正依赖的是 B2B Direct Connect,不创建任何客体对象,双方各自留在自己的租户里通过信任桥直连

同一个”跨租户访问设置”界面下,藏着两个长得像却完全不同的协议

意外收获:比手动同步通讯录更好的架构

修好之后回看,这套方案带来的价值超出了最初”同步通讯录”这个朴素目标:

  • 文件治理更干净:共享频道的文件存在总部租户自己的一个隐藏 SharePoint 站点里,总部的 DLP、保留策略、eDiscovery 规则天然适用——换成普通的群聊,文件会散落在各自的 OneDrive 里,人一走就很难找回;
  • 身份管理零负担:子公司用户的密码、MFA 全部由他们自己的 Entra ID 管理,子公司那边把某个账号停用,他对总部共享频道的访问立即自动失效;
  • 一次搭桥,长期复用:信任桥一旦建立,以后任何部门要和这家子公司协作,几秒钟就能自建共享频道,不用再走一遍后端配置。

教训

  1. “跨租户目录同步”和”跨租户实时协作”是两个不同的产品能力,不要因为需求听起来像”通讯录同步”就直奔 Cross-Tenant Synchronization——先问清楚终态到底是”对方出现在我的地址簿里”还是”我们能在 Teams 里无缝协作”,两者对应完全不同的配置路径;
  2. “跨租户访问设置”界面里的 B2B Collaboration 和 B2B Direct Connect 页签,默认停在第一个,极易被漏掉——凡是涉及 Teams 共享频道、频道级协作的场景,一律确认走的是 B2B Direct Connect 页签,而不是默认页签;
  3. 诡异的”状态显示错误”往往是身份模型选错了的信号,而不是简单的显示 bug——同步进去的用户被判定为访客对象、状态永远离线,是系统在忠实反映”这本来就不该是访客关系”这件事;
  4. 跨租户信任类的配置改完不要立刻测试——先确认全部四处开关都对,再等几个小时的全球同步窗口,用零客体对象检查和审计日志作为客观验收标准,而不是靠一次测试的运气。
← 全部文章