SSO 配置
为企业客户配置 SAML/OIDC 单点登录,带即时配置。
为什么
企业客户无 SSO 不买你的产品——安全团队要求,IT 团队不逐个配置用户。SSO(SAML 2.0 或 OIDC)让用户用企业身份(Okta、Azure AD、Google Workspace)登录,即时配置在首次登录创建账户免手工入职。集成繁琐(SAML XML、元数据交换、证书轮换)但每客户一次性设置解锁 50-500 席交易。多数 B2B SaaS 在采购阶段丢最大交易因无 SSO。
何时使用
第一个企业客户要求时(通常 >50 席)。SAML 约 1-2 天,OIDC 约 4 小时。仅消费产品可跳过。
如何做
1. 按客户需求选协议:SAML 2.0(传统企业)或 OIDC(现代) - SAML:基于 XML,需元数据交换,Fortune 500 主流 - OIDC:JSON/REST,更易实现,Google/Microsoft 主流 2. 用处理协议复杂度的提供方(WorkOS、Auth0、Clerk) - 不要自己实现 SAML——XML 签名 + 规范化会坏 - 提供方给你每客户连接(IdP 发起或 SP 发起) 3. 客户入职时创建每租户连接 - 他们提供 IdP 元数据 URL 或 XML;你向提供方注册 - 把他们目录组映射到应用角色(如"工程"→admin) 4. 在回调 handler 实现即时配置 - 首次 SSO 登录:从 IdP 属性创建用户(邮箱、姓名、组) - 后续登录:更新组/属性(处理他们 IdP 的角色变更) 5. 提供发现端点 /sso/login 接受邮箱域 - 用户输邮箱→按域查租户→重定向到他们 IdP - 避免每客户登录 URL,感觉像正常登录
示例
// WorkOS 驱动的 SSO 回调
import { WorkOS } from "@workos-inc/node";
const workos = new WorkOS(env.WORKOS_API_KEY);
export async function GET(req: Request) {
const { code } = parseQuery(req.url);
const { user, organizationId } = await workos.userManagement.authenticateWithCode({
client_id: env.WORKOS_CLIENT_ID, code,
});
// 即时配置
const dbUser = await db.user.upsert({
where: { email: user.email },
create: { email: user.email, orgId: organizationId, role: mapRole(user.groups) },
update: { role: mapRole(user.groups) }, // 每次登录同步角色
});
await setSession(dbUser);
redirect("/dashboard");
}常见问题
- ⚠硬编码 IdP 元数据而非每租户存储,加第二个客户要改代码。
- ⚠不处理 IdP 发起登录(主动 SAML),点 Okta tile 的用户得错误。
- ⚠忘后续登录同步组/角色变更,降级用户保留 admin 访问。
- ⚠不提供无客户真实 IdP 测 SSO 的方式——用测试 IdP(WorkOS 沙箱)QA。
最佳实践
- ✓每租户 IdP 连接配置存 DB,新客户入职是数据变更非部署。
- ✓每次 SSO 登录记 IdP、租户和断言属性——企业安全团队会要此审计轨迹。
- ✓优雅处理证书轮换:定期取 IdP 元数据,无代码变更更新签名证书。
- ✓先提供 OIDC(双方更易)仅当客户 IdP 不支持时回退 SAML。