developers,

五分钟理解什么是 OIDC

叶祖伟 叶祖伟 Follow Feb 18, 2020 · 2 mins read
五分钟理解什么是 OIDC
分享

OIDC 的全称是 OpenID Connect,是一套基于 OAuth 2.0 的认证 + 授权协议,用于用户身份认证,将用户数据安全地暴露给第三方。

OIDC 与 OAuth 2.0 有何不同?

OAuth 2.0 是用于授权的行业标准协议。 OAuth 2.0 致力于简化客户端开发人员的工作,同时为 Web 应用程序,桌面应用程序,移动电话和物联网设备提供特定的授权流程。

以上是 OAuth 2.0 的官方定义。我们举一个实际的例子,你在登录京东的时候,会发现在京东的登录框中有使用 QQ 登录、使用微信登录的按钮,这些地方就是 OAuth 2.0 协议的用武之地。京东希望从 QQ 获取你的 QQ 用户数据,从而完成在京东的注册,这就需要数据的主人——你的授权。完成授权之后, QQ 会给京东一个 access_token,京东携带这个凭证,就能以你的名义,以及你授予此网站的权限(例如你授权京东能够访问你的个人信息而不是转账能力),访问你在 QQ 服务器上的数据,从而获取你的信息,在此过程中,你无须告诉京东你的 QQ 账号和密码,你输入账密信息的时候,是在腾讯的服务器完成的认证。

OIDCOAuth 2.0 相比,多了认证的能力。不但能够返回用户的 access_token,让第三方通过 access_token 调用用户授权过的接口(用户授权),还可以返回用户的 id_token,第三方可以将 id_token 用作用户身份标识(用户认证)。

回到刚才的例子,京东获取到 QQ 颁发的 access_token(是一个随机字符串)之后确实能够获取到你的信息,但是如果不借助其他手段,是不具备用户身份认证功能的。而在 OIDC 协议中,获取 access_token 的同时,会返回一个 JWT 格式的 id_token,可直接用作身份标识,供第三方确认用户身份。

JWT Token 是这个样子的:

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

格式为“点分 base64 编码”,一共三段,第一部分叫作头部(JOSE Header),第二部分叫作荷载(Payload),第三部分叫作签名(Signature)。其中的签名根据头部、荷载和一个密钥计算得出,不可伪造。

base64 解码之后是这样子的:

{"typ":"JWT", "alg":"HS256"}.{"iss":"joe", "exp":1300819380, "http://example.com/is_root":true}.<签名>

更多 JWT 知识请参考 JWT 规范

总结成一句话:OAuth 2.0 能做的 OIDC 都能做,OAuth 2.0 不具备的认证能力,OIDC 也具备。

OIDC 协议的应用场景

所有使用 OAuth 2.0 的场景都可以升级为 OIDC 协议,OIDC 协议是 OAuth 2.0 的超集。以下是一些 OIDC 协议的应用场景:

  1. 社会化登录场景,网站登录框上常见许多按钮「使用 XXX 登录」。
  2. 物联网设备的身份认证和授权。
  3. 企业内多个应用统一身份,单点登录。
  4. 开放平台对外暴露应用数据,做用户认证与授权。
  5. Serverless 中的身份层。

OIDC 协议是 OAuth 2.0 协议的下一代,是身份认证协议升级的不二之选。 OIDC 协议中的四个主体 在介绍 OIDC 授权模式之前,先要明确四个主体:第三方应用、资源服务器、资源所有者、认证授权服务器。我们继续沿用前文京东与 QQ 登录的例子。

P.S. QQ 使用的是变种 OAuth 2.0 协议,并不完全符合 OIDC 规范,在此假设 QQ 使用 OIDC 协议进行对外数据授权。

第三方应用

京东的角色是第三方应用。

资源服务器

QQ 的个人信息存放于资源服务器。

资源所有者

用户是 QQ 账号的所有者。

认证授权服务器

QQ 的授权服务器负责用户的身份认证和授权,管理第三方应用、受保护资源、资源所有者之间的关系。

四者关系

OIDC 的三种授权模式

Authorization Code Flow

应用最为广泛的是授权码模式,此模式的交互过程如下图:

授权码模式

  1. 第三方应用访问认证服务器的授权链接。(用户在京东网站登录框点击使用 QQ 登录)
  2. 用户与认证服务器完成身份认证。(浏览器跳转到 QQ 授权页面,用户输入 QQ 号和密码)
  3. 认证服务器向第三方应用返回授权码 code。(QQ 服务器将用户的浏览器重定向,将授权码发送到京东服务器)
  4. 第三方应用携带授权码访问认证服务器的 token 接口。(京东服务器携带授权码与 QQ 服务器交互)
  5. 认证服务器返回 access_tokenid_token 给第三方应用。(QQ 服务器返回 access_token 和 id_token 给京东服务器)

此后,第三方应用可以利用 access_token 到资源服务器获取用户的信息,完成在第三方应用的注册和登录业务,并可以将 id_token 作为用户的身份凭证,存放在前端。第三方应用的前端需要访问受保护的资源(例如用户账单信息、购物车)时需要携带 id_token,后端验证 id_token 合法性,核实用户身份之后,返回相关资源数据。

OIDC 认证时相关 Token 解释

OIDC 认证时会签发两种 Token,一类叫 id_token,还有一类叫 access_token。

id_token 是用户身份的凭证,只起到判定用户身份的作用

id_token 示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1ZTQ5NjBkZmJkOTE1OGZiODQ0OTAzYTkiLCJiaXJ0aGRhdGUiOiIiLCJmYW1pbHlfbmFtZSI6IiIsImdlbmRlciI6IiIsImdpdmVuX25hbWUiOiIiLCJsb2NhbGUiOiIiLCJtaWRkbGVfbmFtZSI6IiIsIm5hbWUiOiIiLCJuaWNrbmFtZSI6IiIsInBpY3R1cmUiOiJodHRwczovL3VzZXJjb250ZW50cy5hdXRoaW5nLmNuL2F1dGhpbmctYXZhdGFyLnBuZyIsInByZWZlcnJlZF91c2VybmFtZSI6IiIsInByb2ZpbGUiOiIiLCJ1cGRhdGVkX2F0IjoiIiwid2Vic2l0ZSI6IiIsInpvbmVpbmZvIjoiIiwiY29tcGFueSI6IiIsImJyb3dzZXIiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNF82KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvODAuMC4zOTg3Ljg3IFNhZmFyaS81MzcuMzYiLCJkZXZpY2UiOiIiLCJsb2dpbnNfY291bnQiOjEsInJlZ2lzdGVyX21ldGhvZCI6ImRlZmF1bHQ6dXNlcm5hbWUtcGFzc3dvcmQiLCJibG9ja2VkIjpmYWxzZSwibGFzdF9pcCI6IjEyMS4yMS41Ni4xNzEiLCJyZWdpc3Rlcl9pbl91c2VycG9vbCI6IjVjOTU5MDU1NzhmY2U1MDAwMTY2Zjg1MyIsImxhc3RfbG9naW4iOiIyMDIwLTAyLTE2VDE1OjMzOjUyLjQ0NFoiLCJzaWduZWRfdXAiOiIyMDIwLTAyLTE2VDE1OjMzOjUxLjY2NVoiLCJlbWFpbCI6InRlc3QxQDEyMy5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInBob25lX251bWJlciI6IiIsInBob25lX251bWJlcl92ZXJpZmllZCI6ZmFsc2UsImF0X2hhc2giOiJWYW9sSnVqWXltQjUxNlNGOGNaQkpBIiwic2lkIjoiZGYzMGFlNDgtOTkzMS00YjZlLWI0YzgtMWI5NjRkOGZjOWIyIiwiYXVkIjoiNWQwMWUzODk5ODVmODFjNmMxZGQzMWRlIiwiZXhwIjoxNTgxODcwOTc4LCJpYXQiOjE1ODE4NjczODEsImlzcyI6Imh0dHBzOi8vb2F1dGguYXV0aGluZy5jbi9vYXV0aC9vaWRjIn0.pH-bWm-Im0wnOcUEA-OG_iKwy9DTZlAXuik50HPsfGY

解码后:

{
  "alg": "HS256",
  "typ": "JWT"
}
.
{
  "sub": "5e3a3b2315a0b8398cdaaa08",
  "birthdate": "",
  "family_name": "",
  "gender": "",
  "given_name": "",
  "locale": "",
  "middle_name": "",
  "name": "",
  "nickname": "",
  "picture": "https://usercontents.authing.cn/authing-avatar.png",
  "preferred_username": "",
  "profile": "",
  "updated_at": "",
  "website": "",
  "zoneinfo": "",
  "company": "",
  "browser": "",
  "device": "",
  "logins_count": 8,
  "register_method": "default:username-password",
  "blocked": false,
  "last_ip": "127.0.0.1",
  "register_in_userpool": "5e3a3b2315a0b8398cdaaa04",
  "last_login": "2020-02-16T09:04:09.764Z",
  "signed_up": "2020-02-05T03:48:51.447Z",
  "email": "test@test.com",
  "email_verified": false,
  "phone_number": "",
  "at_hash": "6k-IWJwh-Dd3_hLOay0s7A",
  "sid": "d50a8c9d-23db-4156-80ea-1c82d199d0e9",
  "aud": "5e3a3b2315a0b8398cdaaa0e",
  "exp": 1581948533,
  "iat": 1581944933,
  "iss": "https://core.littleimp.cn/oauth/oidc"
}
.
签名

access_token 是用户授权给第三方应用的一个令牌,第三方应用可以使用这个令牌访问用户在资源服务器上受保护的资源,一般不用于用户凭证和身份标识

access_token 示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJXaXdndEdHYzVMeGtZRUFRY012RFkiLCJzdWIiOiI1ZTNhM2IyMzE1YTBiODM5OGNkYWFhMDgiLCJpc3MiOiJodHRwczovL2NvcmUubGl0dGxlaW1wLmNuL29hdXRoL29pZGMiLCJpYXQiOjE1ODE5NDQ5MzMsImV4cCI6MTU4MTk0ODUzMywic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBwaG9uZSIsImF1ZCI6IjVlM2EzYjIzMTVhMGI4Mzk4Y2RhYWEwZSJ9.MnAAGj6HlYvN3FOAo6PA2cxNxZDZbL3yhxTM3uxnt0M

解码后:

{
  "alg": "HS256",
  "typ": "JWT"
}
.
{
  "jti": "WiwgtGGc5LxkYEAQcMvDY",
  "sub": "5e3a3b2315a0b8398cdaaa08",
  "iss": "https://core.littleimp.cn/oauth/oidc",
  "iat": 1581944933,
  "exp": 1581948533,
  "scope": "openid profile email phone",
  "aud": "5e3a3b2315a0b8398cdaaa0e"
}
.
签名

Implicit Flow

在隐式模式中,认证服务器的授权接口不会返回授权码 code,而是在与用户完成认证后返回 id_token 和 access_token,交互模式如下图所示:

隐式模式

  1. 第三方应用访问认证服务器的授权链接。(用户在京东网站登录框点击使用 QQ 登录)
  2. 用户与认证服务器完成身份认证。(浏览器跳转到 QQ 授权页面,用户输入 QQ 号和密码)
  3. 认证服务器向第三方应用返回 id_token 和 access_token。(QQ 服务器将用户的浏览器重定向,将 id_token access_token 发送到京东前端页面)

隐式模式比授权码模式简单,经常用于将 id_token、access_token 直接返回到前端,方便前端直接存储 id_token 用于证明用户身份。也需要前端自行将 access_token 发回后端,后端用于获取用户的详细信息,这增加了暴露 access_token 的风险。隐式模式不支持返回 refresh_token,即不能从后端刷新 access_token,登录一旦过期需要用户重新登录。

Hybrid Flow

混合模式是以上两种模式的组合,特点是能够在授权接口一次性获取到 code、id_token、access_token,一般 code 会与 id_token、access_token 混合出现,混合模式的交互如下图所示:

混合模式

  1. 第三方应用访问认证服务器的授权链接。(用户在京东网站登录框点击使用 QQ 登录)
  2. 用户与认证服务器完成身份认证。(浏览器跳转到 QQ 授权页面,用户输入 QQ 号和密码)
  3. 认证服务器向第三方应用返回 code、id_token 和 access_token。(QQ 服务器将用户的浏览器重定向,将 id_token access_token 发送到京东前端页面)
  4. 第三方应用携带授权码访问认证服务器的 token 接口。(京东服务器携带授权码与 QQ 服务器交互)
  5. 认证服务器返回 access_tokenid_token 给第三方应用。(QQ 服务器返回 access_token 和 id_token 给京东服务器)

混合模式可以灵活满足 code、id_token、access_token 的各种处理方式,可以在享有隐式模式便利的同时,利用 code 获取 refresh_token,从而可以在后端刷新用户 access_token,不必重复让用户登录。

总结

OIDC 协议是 OAuth 2.0 协议的超集,是可以替代 OAuth 2.0 的下一代身份认证协议,能够解决认证 + 授权两个问题。OIDC 的授权流程与 OAuth 2.0 完全一致,能够保持向下兼容。

授权服务器的意义在于管理第三方应用、受保护资源、资源所有者之间的关系,让互相不信任的应用之间安全地暴露数据——应用之间约定好某种规范,按照这种规范,就能在用户授权的前提下,安全地将数据暴露给第三方,而第三方也无需获知用户的账密信息。

id_token 是用户的身份凭证,access_token 是用户的授权凭证

OIDC 有三种授权模式,分别是授权码模式、隐式模式、混合模式。授权码模式中只能获取到 code;隐式模式中只能获取到 access_token id_token;混合模式中都能够获取到。

叶祖伟
Written by 叶祖伟
Fullstack developer who plays music.