SSO、OAuth2、与 OpenID connect

本系列文章的思想,都融入了 让 Java 再次伟大 这个全新设计的脚手架产品中,欢迎大家使用。

授权与认证

上一章我们一直在反复阐述一个事实: OAuth2 协议是用来解决用户对软件授权的。为何要如此强调这个事实呢?因为授权、认证、单点登录非常容易被混淆。
用户认证是指证明自己的身份。认证有时候会和授权一起使用,就像你去酒店必须首先用身份证证明你的身份,酒店才会授予你使用酒店服务的权利一样。

OAuth2 与 OIDC

今天要介绍的是 OpenID connect 简称 OIDC 是一个关于第三方用户认证的标准化协议。这个协议是建立在我们之前介绍的 OAuth2.0 的基础上的。这又是一个容易混淆的地方:虽然授权和认证在语义上明显不同,但是他们却使用类似的协议来解决问题。还记得之前我们谈到过 OAuth2.0 是一个授权协议,但是他的功能不仅仅如此。OAuth 可以被用来解决任何问题,身份认证就是其中一种。
于是,基于 OAuth 2.0 的协议流程,第三方用户认证协议 OpenID connect 就被设计出来了。所以 OIDC 是 OAuth2.0 的超集,但是认证并不是授权的超集。

OIDC 授权码许可类型流程简介

是的,OIDC 也有两种常用类型:授权码许可类型与隐式许可类型。由于 OIDC 在 OAuth2.0 的基础上被设计出来,所以 OAuth2.0 的流程基本上就是 OIDC 的流程。

在 OIDC 的流程中,相对 OAuth2.0 有 3 个变化。

  1. 授权服务器 + 资源服务器 = 认证服务器。
  2. 根据授权码获取的 token 中包含 id_token。
  3. 用户详情可以使用 UserInfo 端点获取。
    认证服务器的变化很容易理解,由于身份认证不需要使用特定资源只需要对身份认证,所以整合了授权服务器和资源服务器合并为认证服务器。
    但是单独设计 id_token 的理由是什么呢?在授权的场景中,access_token 在协议中是对客户端透明的,不需要被解析。而身份认证需要告诉客户端用户的具体身份;另外 access_token 的用处是访问受保护资源,这是属于授权的概念而不是属于身份认证的概念;最后授权的有效时间和身份认证的有效时间很可能不一样,所以单独设计了 id_token。

id_token 是一个内容基于 jwt 格式的身份令牌(结构如下)。客户端通过解析这个令牌获取用户的登录认证数据以后,就可以为用户提供基于认证中心的第三方登录功能了。

当然偶尔这个 jwt 的有效载荷会更加充实一点:

{
  "iss": "http://server.example.com",
  "sub": "248289761001",
  "aud": "s6BhdRkqt3",
  "nonce": "n-0S6_WzA2Mj",
  "exp": 1311281970,
  "iat": 1311280970,
  "name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "gender": "female",
  "birthdate": "0000-10-31",
  "email": "janedoe@example.com",
  "picture": "http://example.com/janedoe/me.jpg"
}

至于 UserInfo 端点,由于 jwt 格式的 id_token 并不包含过多的用户业务信息,而在用户体验上客户端又需要向用户展示头像、昵称等内容,所以 OIDC 定义了客户端可以使用 access_token 访问 UserInfo 端点获取用户详情的标准化接口。

HTTP/1.1 200 OK
Content-Type: application/json

  {
   "sub": "example@hotmail.com",
   "name": "example",
   "given_name": "example",
   "family_name": "example",
   "preferred_username": "example@hotmail.com",
   "email": "example@gmail.com"
  }

同时这也是 access_token 用于访问受保护资源,id_token 用于身份认证的一次结合应用。
说了这么多,那学习 OIDC 有什么用呢? OIDC 的其中一个用处就是可以用来构建一个单点登录系统(SSO)。

一个标准化的 SSO 场境

假设企业为了自身的运营需要分别部署了 2 个系统:「A、B」。两个系统上线时间不同,提供的业务服务不同,用户体系与认证逻辑不同。所以这两个系统是完全「互不相通」的。
现在需要在不影响现有系统逻辑的前提条件下,提供「一次登陆、多端有效」的功能。

经过构思,我们决定构建统一登陆中心;接着让两个系统都认可统一登陆中心的认证结果,来达到「最小化改动」现有系统的前提下实现 SSO 的功能。回顾上面的知识,OIDC 协议中的身份认证服务器就可以满足这一要求。

SSO 单点登录系统

注意这也是一个容易搞错的知识点:没有任何规定要求必须使用 OIDC 来构建 SSO。实际上你完全可以不使用 OIDC,或是使用 OIDC 的隐式许可类型流程来构建一个 SSO,这都完全取决于你的选择,况且互联网上运行的大部分 SSO 都并没有严格遵守 OIDC 规范。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值