前置知识
认证 :只需要做一件事,认证你是谁,即你这个【人实体】对应的特征标签属性:
姓名、工号、部门。比如每个人头上都有很多标签类型,比如:代号标签-你的姓名 / 角色标签-系统管理员 / 部门标签-技术部 / 兴趣标签-爬山/打球。而认证就是把你这个实体人 和 对应的标签类型 精准匹配上,对应到系统上由于识别不到实体,所以此时实体就是当前登录系统的这个账号 <=> 能对应哪些标签类型【代号标签-姓名、部门标签-技术部、角色标签-系统管理员、...】。这就是在系统中要做的事:账号 <=> 标签映射授权
这些标签种类有很多,但是重要的标签就那几个,比如你的角色标签,不同的角色标签能干的事是不一样的,比如你是
学生,那么你可以享受打折、如果你是老板,那么你可以参与企业内部会议但如果你没有获得老板标签,而只是获得一个NPC标签那你就没有这个权利参加,也就是说,如果你想有更大的权利,你就需要获得对应的标签。是不是很像升级打怪。 那么为什么获得老板标签能参加内部会议,因为我们参与会议和老板这个角色进行了角色绑定。即给这个角色赋予了这个权限,这个操作就是"授权"。就好比:领导可以决定发展方向,为什么他能决定,不是因为这个人本身实体,而是这个人有一个领导标签,谁有这个标签谁就有这个权限。RBAC 干的事:给角色绑定操作权限标签这种针对角色标签的授权,我们称为RBAC。
OAuth2/OIDC 干的事:跨系统授权。对于没有本系统账号,级跨系统访问的用户,进行的访问授权
对于拥有本系统账号的用户,进行的访问授权就是普通登录授权
那OAUTH和oidc做的事有什么区别? oauth解决的是什么问题?访问系统的两种情况:
- 如果你在这个系统注册登录过,就一定会有一个系统角色,或者给你这个用户赋予一个角色,你也能访问这个系统。
- 如果我想绕过注册就访问这个系统,可不可以呢?oauth就是来解决这个问题的。我可以给你一个访问令牌,你拿着这个令牌就可以访问系统。
好,那现在你拿着令牌可以进入系统访问了,但是有一系列问题问题:
安全问题:你进入了系统后,显示你的用户名是什么?显示unknown嘛?不知道你是谁,你的访问记录怎么记,一个黑户(sso登录的本质就是确认你是谁,光给了令牌算啥,被偷了咋办)?系统RBAC操作问题:你没有姓名也就算了,你是那个角色?你是哪个角色决定你能看哪些数据,做哪些操作?总不能给unkonwn用户单独搞个操作权限吧,那不给unkonwn用户搞个角色,你进入系统又啥也看不到(啥也操作不了),oauth给你令牌让你进来,也是白给,没有意义。如果sso的实现没有解决上面两个问题,只给访问权限,但没法快速、标准确认操作者身份,就不叫 "登录",只能叫 "临时授权调用接口"。
所以sso要解决的是:访问 + 身份识别 + 权限打通,这三件事,而不仅仅是访问这一件事。
问题:如果我只用 oauth(不用OIDC)能不能解决SSO单点登录的:访问 + 身份认证 + 权限打通,这三个主要问题?
能,流程是这样:
- 子系统无登录 → 跳 IAM 授权页,走 OAuth 授权码模式
- 用户登录 IAM,同意授权,返回 code
- 子系统后端用 code 换取
access_token(只有车票,没有身份证)- 业务系统拿着 access_token 调用 IAM单独一个接口 :
/userinfo- 拿到用户 ID、姓名、部门,才算知道 "当前是谁登录"
- 再根据用户 ID 查 RBAC 权限,完成登录鉴权
单点免登也能实现:浏览器里 IAM 根域存在登录 Session Cookie,下次别的应用跳转过来不用再输密码,直接发 code,依旧可以拿到 token。
所以单纯 "能访问系统" 这个需求,纯 OAuth 完全能搞定。
可见,我们即使不用OIDC也能实现SSO的三大件:访问授权 + 身份认证 + 权限打通,那为什么 SSO 一定要加上 OIDC?也就是强制带上 id_token?
- 少一次多余接口请求
- 没有统一标准,对接成本爆炸:OAuth 没有规定
/userinfo返回哪些字段、字段名叫什么。A 业务系统:用户 id 叫 uidB 业务系统:用户 id 叫 userIdC 业务系统:主键叫 id每个前端、后端接入都要自己适配字段映射,每接一个系统就要改一遍解析逻辑。OIDC 强制规范固定字段:sub全局唯一用户标识、name姓名、email邮箱所有接入方解析规则一模一样,复制粘贴接入模板即可。 - 天然自带过期、防篡改,不用自己额外校验: id_token 是标准 JWT:自带签发方、过期时间、签名校验。后端直接验签,就能确认这张身份凭证没被篡改、没过期。 纯 OAuth 方案:access_token 只是访问凭证,本身不绑定用户身份;一旦 token 泄露,攻击者调用
/userinfo就能获取他人身份,服务端很难溯源判定使用者是谁。
而为了解决上面两个问题,就需要对你的身份进行验证,这样才能给你
所以sso登录表面需求只是让你可以跨系统访问,但是背后必须要解决的需求是(捆绑):页面右上角的用户名、访问人日志、登录人系统内操作权限。 oidc是确认你这个账号有哪些角色标签,方便你进入系统后能执行哪些操作,看到哪些数据。
OIDC(openID Connect),在OAuth2.0协议上增加了一层身份认证协议逻辑。
做 SSO 单点登录 = 用 OIDC(OAuth2.0 授权码模式 + id_token 身份凭证)
theme: cyanosis
| 协议 | 核心作用 | 有无 id_token | 适合场景 |
|---|---|---|---|
| OAuth2.0 | 资源授权 | 无 | 微信登录、给 APP 授予相册 / 定位权限 |
| OIDC | 身份认证 + 授权 | 有 | 企业 SSO 单点登录、多系统统一账号 |