OpenID Connect 1.0是建立在OAuth 2.0上的一个身份验证机制,它允许客户端通过授权服务对用户进行认证并获取简单的用户信息。

前置知识:读者需要了解OAuth2.0的授权码模式和隐藏模式两种工作流程,要了解JWT、JWE、JWS等概念。这在我的前两篇文章都有详细讲解

概览

名词解释

  • OP:OpenID Provider,即OAuth2.0中的授权服务,用于对用户鉴权

  • RP:Relying Part,依赖方,即OAuth2.0中的客户端,它从OP除获取对用户的鉴权和用户信息

  • ID Token:是一个JWT,包含本次授权的基本信息。具体包含字段如下

    字段 必须? 说明
    iss 发布者,一个https开头的地址
    sub 主体,OP对用户的唯一标识,不超过255个ASCII字符
    aud 客户,即使用者。值为OAuth2.0协议中客户端注册的client_id
    exp 过期时间,遵从RFC 3339协议,即epoch seconds
    iat 签发时间,同上
    auth_time 可选 鉴权时间
    nonce 随机值。两个作用
    一是RP发送时带上,OP响应时带上,用于RP对比
    二是防重放攻击
    acr 可选 Authentication Context Class Reference,暂不知义,忽略
    amr 可选 Authentication Methods References,暂不知义,忽略
    azp 可选 Authorized party,暂不知义,忽略

总体流程

类似OAuth2.0,有一个总体流程和若干细分模式的流程,OpenID Connect协议总体流程为:RP发起请求 -> OP对用户鉴权并获取授权 -> OP响应RP并带上ID Token和Access Token -> RP通过访问凭证向OP请求用户信息 -> OP返回用户信息给RP

+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+

客户鉴权

客户鉴权即OP对客户端进行鉴权,然后将鉴权结果返回给RP。鉴权流程有三种方式:授权码模式、隐藏模式、混合模式。如果了解OAuth2.0,对前两个模式一定不会模式,OpenID流程类似,而混合模式则是前两种模式的结合。具体OP采用什么模式,取决于RP请求时response_type给的值。

response_type 采用的模式
code 授权码模式
id_token 隐藏模式
Id_token token 隐藏模式
code id_token 混合模式
code token 混合模式
code id_token token 混合模式

规律:id_token和token等同:只有id_token或/和token的使用隐藏模式,只有code的使用授权码模式i,同时存在他们的则使用混合模式

授权码模式

总计八个步骤

  1. RP准备用于鉴权请求的参数
  2. RP发送请求,给OP
  3. OP对用户鉴权
  4. OP手机用户的鉴权信息和授权信息
  5. OP发送授权码给RP
  6. RP使用授权码向一个端点换取访问凭证。协议称之为Token端点,但没说这个端点是不是由OP提供的。不过一般来说是
  7. RP收到访问凭证,包含ID Token、Access Token
  8. 客户端验证ID Token,并从中提取用户的唯一标识。前面说过这是一个JWT,唯一标识就是subject identifier

授权码的请求与响应

其中RP准备的请求参数包含OAuth2.0规定的所有字段,也包含一些额外的字段

参数 必须? 来自OAuth2.0? 说明
scope 写死,openid
response_type 写死,code
client_id RP在OP处注册得到的唯一标识
redirect_uri 用于OP鉴权成功后的回调地址,RP在OP处注册时提供
state 推荐 请求来回中包含的不透明值,用户防范CSRF攻击
response_mode OP返回数据的模式
nonce 会被放在ID Token的nonce字段,用于防重放攻击
display 定义OP通过什么方式展示用户鉴权界面
page:完整的网页
popup:弹窗
touch:触摸设备
wap:“feature phone” type display
prompt 定义OP通过什么方式对用户二次鉴权
none:不进行二次鉴权
login:重新登录
consent:获取用户同意使用上次采集到的结果即可
select_account:选择用户账户
max_age 本次鉴权的有效期。超过该时间后,OP必须对用户再次进行鉴权
ui_locales 用户使用的区域信息
Id_token_hint 忽略
login_hint 忽略
acr_values 忽略

如果授权成功,得到的返回会包含code、state等参数,举个例子

HTTP/1.1 302 Found
Location: https://client.example.org/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=af0ifjsldkj

如果授权失败,也会有相应的错误码,具体参考手册的3.1.2.6

凭证的请求与响应

这个就完全和OAuth2.0一样了。

请求上主要包含:grant_type写死authorization_codecode填上一步获取的授权码、redirect_uri填上一步的重定向地址,举个例子

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
# 你可能注意到这里有个Basic鉴权,这是因为Client也是需要被验证的
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JWgrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

响应上多出一个id_token字段,举例如下

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache{"access_token": "SlAV32hkKG","token_type": "Bearer","refresh_token": "8xLOxBtZp8","expires_in": 3600,"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6qJp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJNqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7TpdQyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoSK5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
}

在上面的每一方,比如OP收到请求、RP收到响应,都会对得到的数据进行验证,我们都忽略了,不过这里重点将RP收到ID Token后的验证逻辑列出来

  1. 依据JWT协议解密该Token
  2. iss字段必须匹配RP提前获取到的OP的issuer值
  3. aud字段必须是RP在OP处注册时填写的client_id
  4. 如果包含多个aud字段,则还要验证azp字段
  5. 如果azp字段存在,则它的值必须是RP在OP处注册时填写的client_id
  6. 如果ID Token是RP直接从OP处获取,没有走授权码这一步(比如走隐藏模式的流程),必须走JWS流程验证该JWT的签名
  7. alg的值要么为默认的RS256,要么是RP在OP处注册时通过id_token_signed_response_alg字段指定的算法
  8. exp所展示的时间必须比当前时间晚
  9. iat可以用来识别签发时间过久的JWT,太久的可以拒掉,多久算久,这个取决于RP自己
  10. nonce必须和请求授权码时对应上
  11. acr必须和请求授权码时对应上
  12. 接和auth_time、max_age,可以判断举例上一次时间是不是太久,从而决定是否需要重新发起鉴权请求

隐藏模式

这个模式就比较简单了

  1. RP准备请求参数
  2. RP发送请求
  3. OP认证用户
  4. OP获取用户的认证和授权信息
  5. OP发送ID Token,可能还有Access Token给RP
  6. RP验证ID Token,提取用户的标识

请求

请求参数和授权码模式基本一样,这里列出差别

  • response_type:id_token,或者id_token token,差别是,如果加上token,步骤5会返回Access Token,否则就么有
  • redirect_uri:处于安全考虑,这个地方必须使用HTTPS传输
  • nonce:这个变成了必须的

响应

给个例子就好了

HTTP/1.1 302 Found
Location: https://client.example.org/cb#access_token=SlAV32hkKG&token_type=bearer&id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso&expires_in=3600&state=af0ifjsldkj

与前面不同的是,这里会多一个Access Token的验证,它要结合ID Token中的at_hash字段验证

  • 使用ID Token中头部alg字段指定的算法对Access Token进行哈希
  • 对哈希值进行base64url编码,取左半边
  • 上一步得到的值必须和ID Token中的at_hash字段指定的值匹配

混合模式

  1. RP准备请求
  2. RP发送请求给OP
  3. OP对用户鉴权
  4. OP采集用户的鉴权和授权信息
  5. OP发送给RP授权码,同时根据请求时指定的response_type,发送额外的参数
  6. RP通过授权码向OP请求
  7. RP从OP处得到ID Token和Access Token
  8. RP验证ID Token,解析用户的唯一标识

授权码请求

混合模式在response_type上做文章,允许的值包括:code id_tokencode tokencode id_token token。可以看出,在授权码请求这一步,可能会返回授权码、ID Token、Access Token。下面是一个返回授权码和ID Token的例子

HTTP/1.1 302 Found
Location: https://client.example.org/cb#
code=SplxlOBeZQQYbYS6WxSbIA
&id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
&state=af0ifjsldkj

如果返回值有ID Token,它会包含授权码的签名,对应其c_hash字段,计算方式和隐藏模式的Access Token验证差不多。

至此,混合模式看起来很奇怪,体现在两处

  • ID Token既能在授权码请求时返回,也能在Access Token请求时返回
  • Access Token也有上面的情况

这样做有什么意义呢?

小结

ID Token的意义,主要在于以安全的方式分发用户的唯一标识,Access Token才是用来作为访问凭证的。

获取用户信息

上面介绍了获取访问凭证之前的动作,这里介绍使用访问凭证访问ID Token指定的用户的信息的问题。

能获得什么

获得的内容和请求访问凭证时传的scope有关,具体如下。

字段 scope 说明
sub - 唯一标识,对应JWT的sub
name profile 用户全名
given_name profile
family_name profile
middle_name profile 中间名,这个某些文化有关
nickname profile 昵称
perferred_username profile 用户希望展示给RP的名字
profile profile 用户的概览信息的页面URI
picture profile 用户图片的URI
website profile 用户的网站或者博客URI
email email 用户邮箱
email_verified email 邮箱是否通过验证。如果没有,这可能是用户随便填写的一个邮箱
gender profile 性别
birthdate profile 生日
zoneinfo profile 用户所处时区信息
locale profile 用户所处地域,语言环境
phone_number phone 电话号码
phone_number_verified phone 电话号码是否通过验证
address address 地址,这是一个JSON对象
updated_at profile 用户的这些信息最后一次被更新的时间,epoch seconds

scope可以指定多个值,得到的结果就是并集。比如scope=profile email phone address

一个成功的例子

HTTP/1.1 200 OK
Content-Type: application/json{"sub": "248289761001","name": "Jane Doe","given_name": "Jane","family_name": "Doe","preferred_username": "j.doe","email": "janedoe@example.com","picture": "http://example.com/janedoe/me.jpg"
}

另类获取信息的方式 - claims

可以在请求时加上claims参数,指定能够从用户信息端点或者在ID Token中包含什么信息,它是一个类似json schema的东西,如下是例子:要求给的字段,以及字段是否必要。

{"userinfo":{"given_name": {"essential": true},"nickname": null,"email": {"essential": true},"email_verified": {"essential": true},"picture": null,"http://example.info/claims/groups": null},"id_token":{"auth_time": {"essential": true},"acr": {"values": ["urn:mace:incommon:iap:silver"] }}
}

总结

理解了OAuth2.0的工作流程,再理解OpenID Connect就很容易了,相较而言,它的特点如下

  • OP = 授权服务+资源服务,资源服务的唯一作用就是分发用户信息
  • 规定了用户信息包含的内容
  • Token响应中多了ID Token,它用来指定用户ID,以便在访问用户信息时作为标识
  • ID Token使用了JWT
  • 多了混合模式

OpenID Connect详解相关推荐

  1. 【网络编程】非阻塞connect详解

    一.为什么使用非阻塞connect TCP连接的建立涉及一个在三路握手过程,阻塞的connect一直等到客户收到自己的SYN的ACK才返回,这需要至少一个RTT时间,RTT时间波动很大从几毫秒到几秒. ...

  2. 信号与槽的Connect详解

    QT通过connect关联信号和槽函数 一.Qt5以前的写法 Qt5以前的connect有以下几种: bool connect(const QObject *, const char *,const ...

  3. iOS 内购详解-代码篇

    内购项目-代码篇 一.分步骤说明 1.获取商品列表 2.苹果服务器返回的可购买商品 3.下单购买商品 4.购买队列状态变化,判断购买状态是否成功 5.交易验证 6.拿到的收据信息是,此App所有购买的 ...

  4. MQTT协议详解 三、MQTT控制包(CONNECT)

    文章目录 系列文章目录 前言 CONNECT(客户端请求连接服务端) 一.固定包头(2字节) 二.可变包头(10字节) 协议名字(6字节) 协议等级(1字节) 连接标识(1字节) Clean Sess ...

  5. java中elapseTime设置新时间,Jmeter系列(44)- 详解 Elapsed time、Latency、Connect Time的含义...

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 前言 在 Jmeter 中一些专业名词我们是需要提前认知的,如下 Elapsed time Latency Connect Time ===== ...

  6. emit python 作用_PyQT5 emit 和 connect的用法详解

    对于PyQT4, PyQT5在一些使用上有着比较明显的变化有很大的变化,让人惊讶是在emit和connect上的一些变化比较有意思,相信也是QT为了更好的和Python相结合做的改进. 先上一张图: ...

  7. emit python 作用,PyQT5 emit 和 connect的用法详解

    对于PyQT4, PyQT5在一些使用上有着比较明显的变化有很大的变化,让人惊讶是在emit和connect上的一些变化比较有意思,相信也是QT为了更好的和Python相结合做的改进. 先上一张图: ...

  8. python emit_PyQT5 emit 和 connect的用法详解

    对于PyQT4, PyQT5在一些使用上有着比较明显的变化有很大的变化,让人惊讶是在emit和connect上的一些变化比较有意思,相信也是QT为了更好的和Python相结合做的改进. 先上一张图: ...

  9. 我的世界connect指令php,我的世界1.11指令大全 1.11指令详解

    我的世界1.11指令大全 1.11指令详解.那下面给大家分享的则是1.11版本中的一些指令哦~那不知道我的世界1.11版本有哪些指令的玩家不妨进来看看下面的介绍吧! 游戏园我的世界官方群:325049 ...

最新文章

  1. EventBus3.0 List事件遇到的坑
  2. 【MM模块】 Classification 分类系统
  3. 编程求一个后缀表达式的值
  4. 【机器视觉】 dev_set_tool_geometry算子
  5. whether logo retrieval will block the application
  6. 360浏览器卸载_陈蛋蛋碎碎念—如何完美地卸载流氓软件
  7. MySQL 高级 ———— MySQL逻辑架构图简介
  8. 西部数据app可导致Windows 和 macOS 提权
  9. [收藏]String与string的区别
  10. MySQL 索引的查询、创建与删除
  11. 如何用c语言写一个简答的整人小程序
  12. php怎么文字加粗体代码,html字体加粗用css设置文字粗体样式
  13. java信鸽推送_记录腾讯信鸽推送服务java
  14. 小学计算机课评课稿,有关于小学信息技术评课稿范文
  15. 个性化不和谐帐户的8种方法
  16. 计算机显示器使用的扫描方式,平板扫描仪怎么用 平板扫描仪使用方法【详解】...
  17. 哪些企业可以做知识产权贯标,你不得不了解的事!
  18. Python设置Latex公式中显示数学字体STIX
  19. yarn : 无法加载文件 ...Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本
  20. CAST和VALIDATE_CONVERSION函数 db官方例子

热门文章

  1. 服务器未响应重新投递,对方服务器未响应重新投递中
  2. 2017 华东师范计算机系暑期夏令营机考
  3. 2023年市场增长10倍,云安全成香饽饽了?
  4. 开源商城:小程序+Vue管理员后台+SpringBoot后台服务
  5. MySQL查询本天、本周、本月数据
  6. postgresql数字类型
  7. netstat -an 结果分析
  8. RTMPose关键点检测实战——笔记3
  9. 四川大学计算机网络课件,四川大学计算机网络课件3
  10. 五角大楼的眼中钉 - 维基揭秘创始人