第1章:OIDC认证概述——定义、作用与OAuth2.0的关系

我们先从一个真实场景聊起。

几年前我接手一个微服务项目,原本用OAuth2.0做资源授权,但业务方要求“用户登录后能直接获取用户昵称和头像”。结果大家硬塞了一个自定义,把用户信息放进access 的scope里,搞得又乱又不安全。后来我改用OIDC,这才发现——该干嘛干嘛,身份信息交给ID ,资源授权留给access ,清清爽爽。

OIDC(OpenID Connect)说白了就是一个基于OAuth2.0的身份认证协议。它不是重新造轮子,而是给OAuth2.0加了一层身份层,专门解决“你是谁”的问题。

1.1 OIDC到底解决了什么?

传统OAuth2.0只关心“允许谁访问什么资源”,不关心“用户是谁”。你想想看:你拿access 去调用/userinfo接口,服务端确实知道你允许访问,但它怎么确认这个背后就是张三?标准OAuth2.0里,access 对资源服务器来说就是个不透明的字符串,没法直接拿到用户身份。

OIDC引入了ID ——一个由授权服务器签名的JWT,里面装着用户的身份信息(sub、name、email等)。客户端拿到ID 后,自己验签就能确认用户身份,不需要再跟授权服务器来回通信。我在项目中就遇到过:有些团队因为不想改代码,直接用OAuth2.0的自定义response做身份校验,结果用户登录后被篡改都查不出来。嗯,这就是坑。

👉 个人经验: 如果你只用OAuth2.0做认证,千万别把用户信息塞进access 的scope里。规范做法是用OIDC的ID 来做身份断言,access 只负责授权。

1.2 OIDC与OAuth2.0的关系

我把这个关系总结成一句话:OAuth2.0是地基,OIDC是房子。

  • OAuth2.0:授权框架,定义了四种授权模式(Authorization Code、Implicit、Client Credentials、Resource Owner Password Credentials),最终颁发access 。
  • OIDC:在OAuth2.0的Authorization Code Flow基础上,增加了scope=openid要求,并在 response里返回ID ;同时还定义了UserInfo Endpoint用于获取更详细的用户信息。

核心区别:OAuth2.0只负责“给钥匙”,OIDC还负责“验身份证”。

维度 OAuth2.0 OIDC
核心产物 Access (不透明) ID (JWT)+ Access
目标 授权(允许执行操作) 认证(确认身份)+ 授权
标准扩展 无强制身份层 OpenID Connect Core 1.0
典型用例 API网关、微服务内部调用 单点登录、用户中心、第三方登录

1.3 OIDC的核心组件

我们快速过一下OIDC里几个关键角色:

  1. RP(Relying Party)——也就是客户端应用,比如你的移动App、前端SPA。
  2. OP(OpenID Provider)——授权服务器,比如Keycloak、Azure AD、Auth0。
  3. ID ——JWT格式,包含iss(签发者)、sub(用户唯一标识)、aud(接收方)、exp(过期时间)、nonce(防重放)等标准声明。
  4. UserInfo Endpoint——保护资源,用access 换取用户详细信息(姓名、邮箱、头像等)。
  5. Subject Identifier——用户的唯一标识,通常在OP范围内保证不重复。

⚠️ 避坑指南: 我曾经踩过一个坑——在SPA前端直接验证ID 。ID 虽然可以验签,但一旦泄露,攻击者能直接冒充用户。正确做法是:ID 只由后端服务验证,前端只管拿授权码,换取的过程必须发生在服务端。

下面这张图展示了OIDC在OAuth2.0之上的拓展关系:

OIDC 与 OAuth2.0 的关系 OAuth2.0 授权框架 核心:客户端授权、令牌颁发、资源访问 授权码模式 / 隐式模式 / 客户端凭证模式 / 密码模式 OpenID Connect 身份层 在 OAuth2.0 基础上增加:ID (JWT)、UserInfo Endpoint、nonce 客户端通过 scope=openid 触发身份认证流程 ID 由 OP 签名,客户端可本地验签 UserInfo 端点需带上 access 调用 . .

1.4 OIDC到底怎么用?一个典型流程

假设用户在你的App里点击“使用Google登录”。来个简化版流程:

  1. App(RP)跳转到Google(OP)的授权端点,带上scope=openid profile email。
  2. 用户登录并授权,Google返回一个authorization code给App。
  3. App用这个code去Google的端点换取access 和ID 。
  4. App后端验证ID 的签名和声明(iss、aud、exp、nonce)。
  5. 如果还需要更多用户信息(比如头像URL),用access 请求UserInfo端点。

你看,整个过程中ID 是信任的基石。我在生产上就见过有人直接跳过签名验证,结果被伪造ID 攻破了业务。记住一句话:信任但验证?不——直接验证,别信任。

⚠️ 重要提醒: ID 中的sub字段是用户唯一标识,不要把它和用户名混淆。换OP时sub会变,需要在业务侧做映射。

1.5 为什么DevOps要关注OIDC?

你会问:“我搞CI/CD的,学OIDC干嘛?” 我告诉你,现在云原生场景下,临时凭据的签发越来越依赖OIDC协议。比如GitHub Actions可以用OIDC代金券去AWS获取临时AK/SK,不用硬编码密钥。这跟Secrets轮换直接挂钩——我们后面会详细讲。

总结一下本章重点:

  • OIDC = OAuth2.0 + 身份认证
  • 核心产出是ID (JWT),用于断言用户身份
  • 必须使用scope=openid触发OIDC流程
  • ID 要验签,UserInfo端点需要access 调用