题目与使用场景
企业客户把你的 SaaS 作为服务提供商,身份提供商会发送用户和群组变更。同步可能重复、乱序、延迟或在网络超时后重试。系统需要支持多租户、用户外部标识、组成员关系、软删除、审计和即时撤销,同时遵守 SCIM 2.0 的资源与错误语义。
面试官考察什么
- 是否熟悉 SCIM User、Group、
schemas、过滤查询和 PATCH 语义。 - 能否把外部资源映射、幂等键、并发更新和重试设计成一致的数据流。
- 是否区分
active=false的停用、删除请求和应用内会话撤销。 - 是否能落实租户隔离、令牌权限、审计、速率限制和敏感字段保护。
作答前的澄清问题
先确认身份提供商是否是用户资料的权威来源、是否要求群组推送、是否允许真正删除、同步延迟目标和每租户规模。再确认外部 userName 是否稳定、是否存在邮箱改名、组成员数量上限、是否需要批量接口,以及停用后现有登录会话必须多久失效。不要把邮箱当作永远不变的主键。
30 秒回答框架
我会按租户保存 SCIM 外部资源与本地账户的映射,资源用稳定的外部标识和内部 ID 分离。创建、更新、PATCH、删除和查询都做幂等,记录请求指纹与版本,冲突按条件更新或返回明确错误。active=false 触发停用和会话撤销,删除策略按租户保留期执行。所有请求验证租户、令牌范围和审计链,异步副作用使用可重试队列且不重复发放权限。
分步骤深入解答
- 确定资源边界。 暴露
/Users、/Groups、/ResourceTypes、/Schemas和/ServiceProviderConfig等能力时,明确实际支持的字段和操作。响应中的schemas必须与资源类型一致,未支持的过滤操作返回规范化错误。 - 建立身份映射。 为每个租户保存外部资源 ID、内部用户 ID、来源系统和当前版本。
userName、邮箱等可变属性用于查找或显示,不能替代稳定映射;冲突时拒绝自动合并并进入人工处理。 - 实现幂等与并发控制。 重复 POST 要么返回已有资源,要么按外部请求指纹安全重试;PATCH 逐条应用操作并记录结果。支持
ETag或版本条件时拒绝过期写入,避免旧事件覆盖新资料。 - 处理用户和群组生命周期。
active=false先撤销应用权限、停止新登录并使现有会话失效。真正删除要经过租户保留策略和审计;组成员更新采用集合差异,不能在部分失败时把未确认成员全部移除。 - 隔离异步副作用。 API 写入本地事实表后投递权限同步、欢迎通知和审计事件。队列消息携带租户、资源版本和幂等键;消费者重复执行不应重复授予权限或发送通知。
- 防护与运维。 SCIM 令牌只授予对应租户和操作范围,支持轮换、撤销和过期。限制分页、过滤和批量大小,记录成功、拒绝、冲突、重试和停用延迟;日志脱敏,不记录完整令牌或敏感属性。
高质量示范回答
我会把 SCIM API 视为“外部身份源到本地账户的同步边界”。每个租户都有独立的令牌、外部资源映射和审计链。User 和 Group 资源保留稳定的外部 ID 与内部 ID,字段遵守 SCIM schema;不支持的过滤、PATCH 操作或属性返回策略明确报错,不静默猜测。
写入先落本地事实表,再按资源版本投递可重试的权限副作用。重复请求通过外部 ID、请求指纹和条件版本保持幂等;过期版本拒绝覆盖新资料。active=false 触发权限撤销、停止新登录并使现有会话失效,删除遵循租户保留策略。群组更新使用差异计算,部分失败可重试且不清空未确认成员。观测包括每租户同步延迟、冲突率、停用到会话失效的时间和死信数量。依据包括 RFC 7643、RFC 7644 与 Okta 的 SCIM 实施指南。
常见错误
- 只实现
POST /Users,没有/ServiceProviderConfig、过滤、PATCH、错误类型和分页契约。 - 用邮箱作为唯一主键,邮箱变更后创建重复账户或错误关联旧账户。
- 把超时重试当成新请求,重复发放权限、发送通知或覆盖较新的属性。
- 收到
active=false只隐藏用户,不撤销令牌、权限和现有会话。 - 群组同步失败时直接清空本地成员,造成短暂网络问题变成大范围越权或误删。
追问及应对
如果身份提供商重复发送同一个创建请求怎么办?
按租户和外部资源 ID查找映射,并保存请求指纹或版本。已有资源返回稳定表示;如果请求内容冲突,返回可诊断错误并记录审计,不静默覆盖本地手工修改。
邮箱改名时如何保持账户连续?
使用外部资源 ID到内部账户 ID的稳定映射,邮箱只作为可变属性。改名先校验租户内唯一性,再更新显示和登录别名,不能创建新账户或凭邮箱跨租户匹配。
停用事件与登录请求同时到达时如何保证安全?
权限检查读取可线性化的账户状态或撤销版本;停用事务提高版本并撤销会话。登录签发前再次检查版本,发现已停用则拒绝,即使旧的异步权限任务尚未完成也不能恢复访问。