第一次接触企业身份系统时,最容易混淆的不是协议细节,而是把系统、登录、授权和账号同步当成一件事。
IAM 管的是身份的整个生命周期,包括账号从哪里来、如何登录、能访问什么、调岗时怎样改权限、离职后怎样停用,以及事后如何追查。SAML、OIDC 和 CAS 主要解决登录与单点登录。OAuth 2.0 解决应用访问 API 时的授权问题。SCIM 负责在系统之间创建、更新和停用账号。
Keycloak、Microsoft Entra ID、Okta 和 Apereo CAS 是产品或软件。SAML、OIDC、OAuth 2.0、CAS 和 SCIM 是协议。配置页面里的 ACS、Authorization Endpoint、Token Endpoint 和 SCIM Base URL,才是这些协议在系统中的具体接口。
一、IAM 系统#
没有统一管理时,OA、邮箱、代码仓库和 VPN 各自保存一份用户信息,也各有一套登录页面。新员工入职后,HR 发邮件通知多个管理员开账号,有的当天完成,有的拖到下周。离职同样靠人工通知。只要漏掉一个系统,旧账号就可能继续使用。
IAM 把这些分散的动作串起来。HR 录入工号、部门和邮箱后,系统按照岗位自动创建账号并分配权限。员工登录一次,就能进入已经接入单点登录的应用。调岗时撤掉旧权限,补上新权限。离职时停用登录账号,同时通知下游应用关闭账号。已经签发的会话和令牌是否立即失效,还要看 IdP 与各应用是否支持相应的注销或撤销机制。
人员信息通常保存在目录服务中,常见选择包括 Active Directory、LDAP 和云目录。很多公司以 HR 系统中的在职记录为准,再把必要字段同步到目录。目录保存工号、邮箱、部门和用户组,但它本身不等于登录协议,也不一定直接向业务系统发送 SAML Assertion 或 OIDC Token。
真正处理登录的是 IdP(Identity Provider,身份提供方)。IdP 校验密码、短信验证码或硬件密钥,必要时要求 MFA(多因素认证),然后向业务系统返回登录结果。用户点击“使用公司账号登录”后看到的页面,通常就是 IdP 的登录页面。业务系统不再保存或校验企业密码,只验证 IdP 提供的登录证明。这种一次登录后访问多个系统的体验,就是 SSO(Single Sign-On,单点登录)。
登录成功不代表拥有所有权限。认证回答“你是谁”,授权回答“你能做什么”。有的系统使用用户组和角色控制权限,有的把授权规则交给独立的策略服务。无论采用哪种方式,都不能只验证用户已经登录,还要判断他是否可以进入当前应用,以及是否可以执行当前操作。
账号创建、资料更新、权限变更和停用,也应当同步到下游系统。只接入单点登录,却没有处理离职账号和已有会话,解决的只是登录入口统一,不是完整的身份管理。IAM 还需要保留审计记录,例如谁在什么时间获得了哪项权限、由谁批准,以及这项权限是否仍有保留的必要。
这些能力可以集中在一个产品中,也可以由多个系统配合完成。Microsoft Entra ID 和 Okta 常用于企业身份管理与云应用单点登录。Keycloak 适合自行部署。Apereo CAS 最早广泛用于高校,如今也能支持 SAML、OIDC 和 OAuth。选择产品时,应先确认人员信息从哪里进入目录、登录使用什么协议、权限保存在哪里,以及离职状态能否及时传递给所有相关系统。
IdP 与浏览器、业务系统之间,通常使用 SAML、OIDC 或 CAS 传递认证结果。应用需要访问 API 时使用 OAuth 2.0。IAM 或 IdP 要把账号同步到下游 SaaS 时使用 SCIM。一套企业身份系统中,这几类协议经常同时存在,因为它们解决的问题不同。
二、OAuth 2.0#
OAuth 2.0 解决的是授权,不定义用户登录。假设一个打印应用需要读取网盘文件,用户不必把网盘密码交给打印应用,只需要同意它读取指定文件。授权服务器随后向打印应用签发 Access Token(访问令牌)。这个令牌表示客户端可以按照指定范围访问某个 API,但它本身不负责证明当前用户是谁。
Access Token 可以是不可解析的随机字符串,也可以是 JWT。客户端通常只负责携带它,资源服务器负责验证令牌是否有效、是否发给自己,以及它包含的权限范围是否允许当前操作。
OAuth 2.0 中有四类角色。
- Resource Owner(资源所有者),通常是用户
- Client(客户端),希望访问资源的应用
- Authorization Server(授权服务器),处理授权并签发令牌
- Resource Server(资源服务器),提供受保护的 API
演示环境中,授权服务器和资源服务器可能运行在同一进程里。系统拆开后,必须分清谁负责签发令牌,谁负责验证令牌。
浏览器或移动应用中有用户参与时,通常使用 Authorization Code(授权码)流程,并配合 PKCE。公共客户端必须使用 PKCE,机密客户端也建议使用。两个后台服务以应用自身身份互相调用时,可以使用 Client Credentials(客户端凭证)。只有授权服务器签发了 Refresh Token(刷新令牌),客户端才能用它换取新的 Access Token。
Implicit(隐式模式)会让 Access Token 出现在浏览器的授权响应中,容易造成令牌泄露或重放,当前安全建议是不再使用。Resource Owner Password Credentials(密码模式)要求用户把密码交给客户端,现行 OAuth 安全最佳实践明确要求不得使用。
用户同意授权后,浏览器会跳转到类似下面的地址。
GET /authorize
?response_type=code
&client_id=app-a
&redirect_uri=https://app-a.example/callback
&scope=repo
&code_challenge=...
&state=...http应用拿到 code 后,再从后端调用 Token Endpoint 换取 Access Token。标准 OAuth 2.0 流程不会因为用户完成授权就自动返回 ID Token。没有 ID Token,应用只能确认自己获得了访问仓库的权限,不能把 Access Token 当作用户身份凭证。
三、OIDC#
OAuth 2.0 不提供标准的用户身份信息。OIDC(OpenID Connect)在 OAuth 2.0 之上增加了一层身份认证,并引入 ID Token。ID Token 是 JWT,包含授权服务器对本次用户认证作出的声明。
客户端不能只是解码 JWT、读出姓名后就相信它。至少要验证签名、iss、aud 和 exp,并按所用流程检查 nonce 等字段。sub 是用户在当前签发方下的稳定标识,通常比邮箱更适合当作账号关联依据。邮箱可能变化,也可能在不同租户中重复。
OIDC 中常见的三类令牌用途不同。
- ID Token 交给客户端,用来确认用户身份和本次认证结果
- Access Token 交给资源服务器,用来判断 API 是否允许访问
- Refresh Token 交给授权服务器的 Token Endpoint,用来申请新的 Access Token
不是每次 OIDC 登录都会签发 Refresh Token。客户端必须请求并满足服务端规定的条件,授权服务器才会返回它。
OIDC 请求必须包含 openid scope。需要更多用户资料时,可以增加 profile、email 等 scope,或者携带 Access Token 调用 UserInfo Endpoint。支持标准 OIDC 的“使用 Google 登录”和“使用 Microsoft 登录”,采用的就是这类流程。对于新建的 Web 或移动应用,如果双方都支持 OIDC,通常没有必要再从 SAML 开始。
完成 OIDC 登录后,应用一般还会建立自己的本地 Session。IdP 签发的 Access Token 也不会自动被企业内所有 API 接受。只有令牌的受众、签名、权限范围和其他校验条件都符合要求,某个 API 才能使用这枚令牌。
四、SAML#
SAML 2.0 比 OIDC 更早出现,也不依赖 OAuth。IdP 生成 XML 格式的 SAML Assertion,SP(Service Provider,服务提供方)验证后建立本地 Session。Assertion 可以包含用户标识、认证时间、认证方式,以及工号、邮箱、部门等属性。
下面是常见的 SP 发起登录流程。用户打开业务系统后,SP 发现本地没有 Session,于是通过浏览器把 AuthnRequest 发送给 IdP。IdP 完成认证后,通常让浏览器以 HTTP POST 的方式把 SAML Response 送到 SP 的 ACS(Assertion Consumer Service,断言接收服务)。SP 验证通过后,才允许用户进入系统。
SAML 的安全校验不只是验证 XML 中有一个用户名。SP 还要检查签名、签发方、受众、有效时间、接收地址,以及响应是否对应自己发出的请求。否则,即使 Assertion 格式正确,也可能被错误接收或重复使用。
SAML 在存量企业软件中仍然常见。许多 SaaS 已经提供成熟的 SAML 接口,但 XML、证书和 Metadata 的配置通常比 OIDC 繁琐。新系统可以优先考虑 OIDC。对方只支持 SAML 时,就按 SAML 接入,不必为了统一协议改造整个系统。
五、CAS#
CAS 最早广泛用于高校,国内不少学校和内网门户至今仍在使用。它的核心凭证不是 JWT,也不是 SAML Assertion,而是 Ticket(票据)。
用户在 CAS 登录成功后,CAS 服务端创建 TGT(Ticket-Granting Ticket,登录票据),浏览器保存与这次单点登录会话关联的 TGC(Ticket-Granting Cookie)。访问系统 A 时,CAS 为系统 A 签发一次性的 ST(Service Ticket,服务票据)。系统 A 不自行解析 ST,而是从后端调用 CAS 的校验接口。ST 只能由指定服务使用,并且只能校验一次。
用户随后访问系统 B 时,浏览器会再次跳转到 CAS。由于 TGC 仍然有效,CAS 不再要求用户输入密码,而是为系统 B 签发另一张 ST。这就实现了浏览器中的单点登录。
CAS 把登录状态保留在中心,业务系统只负责校验票据。它很适合传统浏览器门户,但扩展到移动应用和 API 时,通常不如 OIDC 与 OAuth 2.0 自然。
还要区分 CAS 协议和 CAS 服务端软件。CAS 协议描述的是基于票据的单点登录。Apereo CAS 这类产品还可以支持 SAML、OIDC 和 OAuth。对接前要先确认对方要求的是 CAS 协议,还是使用某款 CAS 产品提供的其他协议。已有系统可以继续使用 CAS,新建的互联网应用和 API 则更适合采用 OIDC 与 OAuth 2.0。
六、SCIM 2.0#
SAML、OIDC 和 CAS 通常在用户登录时工作。SCIM(System for Cross-domain Identity Management)在后台同步账号和用户组。
IAM 或 IdP 中负责账号同步的组件充当 SCIM Client,下游应用充当 SCIM Service Provider。下游应用提供 /Users 和 /Groups 等接口,双方使用 JSON 创建和更新数据。员工离职时,通常把用户资源的 active 改为 false,以便保留历史记录和引用关系,而不是直接删除账号。
POST /scim/v2/Users
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "zhangsan",
"emails": [{ "value": "zhangsan@example.com", "primary": true }],
"active": true
}httpSCIM 负责把账号状态传给目标系统,但它不规定业务系统必须怎样处理已有 Session 和 Token。目标系统收到停用状态后,还要按照自身的安全策略关闭登录能力,并撤销仍然有效的会话或令牌。
没有 SCIM 时,企业往往依赖管理员手工开账号、定时发送表格,或者让每个系统单独开发同步程序。人员规模扩大后,最常见的风险未必是登录协议失效,而是离职账号没有及时关闭。因此,企业客户接入 SSO 后,通常还会继续要求账号自动创建、更新和停用。
SCIM 不负责登录。账号同步成功后,用户仍然要通过 SAML、OIDC 或其他认证方式进入系统。
七、这些协议怎样配合#
| 要解决的问题 | 常用协议 |
|---|---|
| 应用代用户访问 API,或者服务之间调用 | OAuth 2.0 |
| 新建 Web 或移动应用的登录与单点登录 | OIDC |
| 对接只支持 XML Assertion 的企业软件 | SAML 2.0 |
| 接入已有的 CAS 门户和高校统一认证 | CAS |
| 入职、调岗和离职时自动同步账号 | SCIM 2.0 |
一种常见的企业架构是,HR 系统保存员工的在职状态,IAM 把人员信息同步到目录和下游应用,IdP 同时提供 OIDC 与 SAML。已有 CAS 门户可以继续保留。新应用使用 OIDC 登录,API 使用 OAuth 2.0,SaaS 账号则通过 SCIM 创建和停用。
如果用户通过 SAML 登录后,还要访问只接受 OAuth Access Token 的 API,不能直接把 SAML Assertion 当作 Access Token。只有授权服务器或网关明确支持 OAuth Token Exchange 等转换机制时,才能用 SAML Assertion 换取 Access Token。接入双方需要事先约定令牌类型、受众、权限范围和信任关系。
判断应该使用哪种协议时,可以先问三个问题。现在要解决的是用户登录、API 授权,还是账号生命周期?系统之间传递的是认证结果、访问令牌,还是用户资料?目标系统已经支持哪些标准?把这三个问题分开,协议之间的关系就清楚了。