协议概述
什么是 OIDC
OpenID Connect (OIDC) 是一种建立在 OAuth 2.0 协议之上的身份认证协议。OIDC 通过在 OAuth 2.0 的基础上引入了标准化的身份认证流程,为应用程序提供了更为完整的身份验证解决方案。
OIDC 定义了一些角色和术语,包括:
- 客户端(RP): 使用 OIDC 进行认证和授权 的应用程序,例如 Web 应用、原生移动应用等。
- 认证服务器(OP): 提供用户认证和授权服务的服务器,负责颁发 ID Token 和访问令牌。
- 用户(EU): OIDC 的最终用户。
- ID Token: 包含有关已验证用户的身份信息的 JSON Web Token(JWT),由认证服务器签名并在向客户端返回时加密。
- 访问令牌(Access Token): 授权客户端访问受保护资源的令牌。
协议流程
- RP(客户端)向 OpenID 提供程序 (OP) 发送请求
- OP 验证 End-User 身份验证并颁发授权
- OP用 ID Token(通常是Access Token)进行响应
- RP携带 Access Token 发送请求到 UserInfo Endpoint
- UserInfo Endpoint返回 End-User 的Claims
下图说明了这些步骤:
+--------+ +--------+
| | | |
| |---------(1) AuthN Request-------->| |
| | | |
| | +--------+ | |
| | | | | |
| | | End- |<--(2) AuthN & AuthZ-->| |
| | | User | | |
| RP | | | | OP |
| | +--------+ | |
| | | |
| |<--------(3) AuthN Response--------| |
| | | |
| |---------(4) UserInfo Request----->| |
| | | |
| |<--------(5) UserInfo Response-----| |
| | | |
+--------+ +--------+
协议参数
客户端向认证服务器发起认证请求,并提供以下参数:
- response_type: 必选,固定为
code
或id_token
或token
或code
id_token
或code
token
或id_token
token
或code
id_token
token
,表示授权类型。 - client_id: 必选,客户端的唯一标识符。
- redirect_uri: 必选,用于接收认证结果的 URI。
- scope: 可选,请求的范围,例如
openid
profile
email
,其中 openid 是必选的。 - nonce: 可选,用于防止重放攻击的随机数,仅在响应类型为
id_token
或code
id_token
或id_token
token
或code
id_token
token
时必选。 - state: 可选,用于客户端的跨站请求伪造(CSRF)保护。
认证服务器对用户进行认证,并返回以下参数:
- id_token: 代表用户身份的 JWT 格式的令牌,包含用户的标识信息和认证信息。
- access_token: 代表访问令牌,用于访问用户授权的资源。
- refresh_token: 代表刷新令牌,用于获取新的访问令牌。
- token_type: 代表访问令牌的类型,一般为
Bearer
。 - expires_in: 代表访问令牌的有效期,单位为秒。
- scope: 代表访问令牌的权限范围。
- state: 用于防止跨站点请求伪造攻击,防止攻击者通过构造恶意 URL,诱骗用户访问认证服务器,获取授权码或令牌。
其中,id_token
是 OIDC 协议独有的,它包含了用户的身份信息和认证信息。OAuth2 协议中只有 access_token
和 refresh_token
。
OIDC VS OAuth 2.0
OIDC(OpenID Connect)协议是基于 OAuth 2.0 协议之上的,因此它们的流程有相似之处,但也有不同之处。
OAuth2.0 实际上只是一种授权协议,不是认证协议。 在 OAuth 2.0 协议中,不管是哪一种授权模式,最终的结果都是返回令牌并赋予客户端一定的权限。OAuth 2.0 协议只解决了授权的问题,客户端只要得到了资源所有者的授权就能访问资源,但实际资源服务器和授权服务器并不知道访问资源的客户端身份。
OIDC 在 OAuth 2.0 协议的基础上增加了身份认证的功能。 主要是通过 ID Token 来传递身份 信息。因此,OIDC 协议的流程中多了一些与身份认证相关的步骤,比如通过授权码换取 ID Token 和用户信息、校验 ID Token 等。 总的来说,OIDC 和 OAuth 2.0 协议的流程相似但并不完全相同,OIDC 在 OAuth 2.0 协议的基础上增加了一些与身份认证相关的步骤和机制,以实现更加安全和可靠的身份认证。
若对 OAuth 2.0 协议不熟悉,可以先了解一遍 OAuth 2.0 的协议规范。
身份令牌 id_token
第三方应用程序在请求访问令牌时,授权服务器除了返回访问令牌 Access Token 之外,还需要返回包含用户身份的 ID Token。
OIDC 的规范里,详细定义了 id_token
的格式,必须为 JWT 格式。对 JWT 格式不熟悉的,可以详见 JWT 应用对接文档。
OIDC 规范中提供了一个 JWK 格式的公钥,供第三方应用程序导入,用于验签 id_token。
实际使用中,需要根据不同的 Client 端传入的不同的授权范围 scope,返回不同的 token,不在这里展开描述。
用户身份接口 user_info
OIDC 增加了一个用户信息 user_info 接口的定义,Client 端可以使用访问令牌 Access Token,请求用户信息。 user_info 接口定义了返回的参数如下
参数 | 类型 | 说明 |
---|---|---|
sub | string | 用户的唯一标识 |
name | string | 用户的名称 |
preferred_username | string | 用户名 |
string | 用户的邮箱地址 | |
email_verified | boolean | 用户邮箱是否完成验证 |
phone_number | string | 用户手机号码 |
phone_number_verified | boolean | 用户手机号码是否完成验证 |
profile | string | 用户的网络主页 URL |
picture | string | 用户的照片头像 URL |
更多资料
- OpenID Connect Core 1.0:https://openid.net/specs/openid-connect-core-1_0.html
- OpenID Connect Discovery 1.0:https://openid.net/specs/openid-connect-discovery-1_0.html
- OpenID Connect Dynamic Client Registration 1.0:https://openid.net/specs/openid-connect-registration-1_0.html
- OpenID Connect Session Management 1.0:https://openid.net/specs/openid-connect-session-1_0.html
- OpenID Connect Front-Channel Logout 1.0:https://openid.net/specs/openid-connect-frontchannel-1_0.html
- OpenID Connect Back-Channel Logout 1.0:https://openid.net/specs/openid-connect-backchannel-1_0.html
- RFC7519:JSON Web Token