目录
定稿 N·萨基穆拉
 NAT.Consulting(曾在 NRI)
 J·布拉德利
 Yubico(曾在 Ping Identity)
 M·琼斯
 自发行咨询(曾于
 微软)
 B·德·梅代罗斯
 谷歌
 C·莫蒂莫尔
 迪士尼(曾在 Salesforce 工作)
 2023 年 12 月 15 日


OpenID Connect Core 1.0 包含勘误表集 2

摘要

OpenID Connect 1.0 是 OAuth 2.0 协议之上的简单身份层。它使客户端能够根据授权服务器执行的身份验证来验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终​​用户的基本配置文件信息。

该规范定义了 OpenID Connect 的核心功能:基于 OAuth 2.0 构建的身份验证以及使用声明来传达有关最终用户的信息。它还描述了使用 OpenID Connect 的安全和隐私注意事项。



目录

1.  简介
    1.1.  要求符号和约定
    1.2.  术语
    1.3.  概述
2.   ID 令牌
3.  身份验证
    3.1.  使用授权代码流程进行身份验证
        3.1.1.  授权代码流程步骤
        3.1.2.  授权端点
            3.1.2.1.  身份验证请求
            3.1.2.2.  身份验证请求验证
            3.1.2.3.   授权服务器对最终用户进行身份验证
            3.1.2.4.  授权服务器获得最终用户同意/授权
            3.1.2.5.  成功的身份验证响应
            3.1.2.6.  身份验证错误响应
            3.1.2.7.  身份验证响应验证
        3.1.3.   令牌端点
            3.1.3.1.  令牌请求
            3.1.3.2.  令牌请求验证
            3.1.3.3.   成功的令牌响应
            3.1.3.4.  令牌错误响应
            3.1.3.5.  令牌响应验证
            3.1.3.6.   ID 令牌
            3.1.3.7.   ID 令牌验证
            3.1.3.8.  访问令牌验证
    3.2.   使用隐式流程进行身份验证
        3.2.1.  隐式流程步骤
        3.2.2.  授权端点
            3.2.2.1.  身份验证请求
            3.2.2.2.  身份验证请求验证 
            3.2.2.3.  授权服务器对最终用户进行身份验证
            3.2.2.4.  授权服务器获得最终用户同意/授权
            3.2.2.5.  成功的身份验证响应
            3.2.2.6.  身份验证错误响应
            3.2.2.7.  重定向 URI 片段处理
            3.2.2.8.  身份验证响应验证
            3.2.2.9.   访问令牌验证
            3.2.2.10.  ID 令牌
            3.2.2.11.  ID 令牌验证
    3.3.    使用混合流进行身份验证
        3.3.1.  混合流步骤
        3.3.2.  授权端点
            3.3.2.1.  身份验证请求
            3.3.2.2.  身份验证请求验证
            3.3.2.3.  授权服务器对最终用户进行身份验证
            3.3.2.4.  授权服务器获得最终用户同意/授权
            3.3.2.5.  成功的身份验证响应
            3.3.2.6.  认证错误响应
            3.3.2.7.  重定向 URI 片段处理
            3.3.2.8.  身份验证响应验证
            3.3.2.9.  访问令牌验证
            3.3.2.10.  授权码验证
            3.3.2.11.   ID 令牌
            3.3.2.12.  ID 令牌验证
        3.3.3.  令牌端点
            3.3.3.1.  令牌请求
            3.3.3.2.  令牌请求验证
            3.3.3.3.   成功的令牌响应
            3.3.3.4.  令牌错误响应
            3.3.3.5.  令牌响应验证
            3.3.3.6.  ID 令牌
            3.3.3.7.  ID 令牌验证
            3.3.3.8.  访问令牌
            3.3.3.9.  访问令牌验证
4.  启动第三方登录
5.  声明
    5.1.  标准声明
        5.1.1.  地址声明
        5.1.2.  附加声明
    5.2.  权利要求语言和文字
    5.3.  用户信息端点
        5.3.1.  用户信息请求
        5.3.2.  成功的 UserInfo 响应
        5.3.3.  用户信息错误响应
        5.3.4.  用户信息响应验证
    5.4.  使用范围值请求声明
    5.5.  使用“claims”请求参数请求声明
        5.5.1.  个人声明请求
            5.5.1.1.  请求“acr”声明
        5.5.2.  个人声明的语言和文字
    5.6.  声明类型
        5.6.1.  正常声明
        5.6.2.  聚合和分布式声明
            5.6.2.1.  汇总声明示例
            5.6.2.2.  分布式声明的示例
    5.7.  声明稳定性和唯一性
6.  将请求参数作为 JWT 传递
    6.1.  按值传递请求对象
        6.1.1.  请求使用“request”请求参数
    6.2.  通过引用传递请求对象
        6.2.1. 引用请求对象的 URI
        6.2.2.   使用“request_uri”请求参数进行请求
        6.2.3. 授权服务器获取请求对象
        6.2.4.   “request_uri” 基本原理
    6.3.  验证基于 JWT 的请求
        6.3.1.  加密请求对象
        6.3.2.  签名请求对象
        6.3.3.
   请求参数组装和验证       
7.  自发行 OpenID Provider
    7.1.  自发行的 OpenID 提供商发现
    7.2.  自发行 OpenID 提供商注册
        7.2.1.  通过“注册”请求参数提供信息
    7.3.  自行发出的 OpenID 提供商请求
    7.4.  自行发布的 OpenID 提供商响应
    7.5.  自发行的 ID 令牌验证
8.  主体标识符类型
    8.1.  成对标识符算法
9.  客户端身份验证
10.  签名和加密
    10.1.   签署
        10.1.1.  非对称签名密钥的轮换
    10.2.  加密
        10.2.1.  非对称加密密钥的轮换
11.  离线访问
12.  使用刷新令牌
    12.1.   刷新请求
    12.2.  成功刷新响应
    12.3.  刷新错误响应
13.  序列化
    13.1.  查询字符串序列化
    13.2.  表单序列化
    13.3.  JSON 序列化
14.  字符串操作
15.  实现注意事项
    15.1. 所有 OpenID 提供商必须实现的功能
    15.2. 动态 OpenID 提供商必须实现的功能
    15.3. 发现和注册
    15.4.  依赖方必须实现的功能
    15.5. 实现说明
        15.5.1.  授权代码实施说明
        15.5.2.  随机数实施说明
        15.5.3.  重定向 URI 片段处理实施说明
    15.6.  兼容性说明
    15.7.  相关规范和实施者指南
16.  安全考虑
    16.1.  请求披露
    16.2.  服务器伪装
    16.3. 令牌制造/修改
    16.4.  访问令牌披露
    16.5.  服务器响应披露
    16.6.  服务器响应否认
    16.7.  请求否认
    16.8.  访问令牌重定向
    16.9.  令牌重用
    16.10.    窃听或泄露授权码(辅助验证器捕获)
    16.11.    令牌替换
    16.12.  定时攻击
    16.13.  其他与加密相关的攻击
    16.14.  签署和加密命令
    16.15.  发行人标识符
    16.16.  隐式流量威胁
    16.17.   TLS 要求
    16.18.  访问令牌和刷新令牌的生命周期
    16.19.  对称密钥熵
    16.20.  需要签署请求
    16.21.  需要加密请求
    16.22.   HTTP 307 重定向
    16.23.   iOS上的自定义 URI 方案
17   隐私注意事项
    17.1.  个人身份信息
    17.2.  数据访问监控
    17.3.  相关性
    17.4.  离线访问
18.   IANA 注意事项
    18.1.   JSON Web 令牌声明注册
        18.1.1.  注册表内容
    18.2.   OAuth 参数注册
        18.2.1.  注册表内容
    18.3.   OAuth 扩展错误注册
        18.3.1.  注册表内容
    18.4.   URI 方案注册
        18.4.1.  登记内容
19.  参考文献
    19.1.  规范性参考文献
    19.2.  资料性参考文献
附录 A.  授权示例
    A.1.  使用response_type=code 的示例
    A.2.  使用response_type=id_token 的示例
    A.3.  使用response_type=id_token 令牌的示例
    A.4.  使用response_type=code id_token 的示例
    A.5.  使用response_type=code 令牌的示例
    A.6.  使用response_type=code id_token 令牌的示例
    A.7.  示例中使用的 RSA 密钥
附录 B.  致谢
附录 C.  通知
§  作者地址




目录

一、简介

OpenID Connect 1.0 是 OAuth 2.0 [RFC6749]Hardt, D., Ed.,“OAuth 2.0 授权框架”,2012 年 10 月。协议 之上的简单身份层 。它使客户端能够根据授权服务器执行的身份验证来验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终​​用户的基本配置文件信息。

OpenID Connect Core 1.0 规范定义了核心 OpenID Connect 功能:基于 OAuth 2.0 构建的身份验证以及使用声明来传达有关最终用户的信息。它还描述了使用 OpenID Connect 的安全和隐私注意事项。

作为背景,OAuth 2.0 授权框架Hardt, D., Ed.,“OAuth 2.0 授权框架”,2012 年 10 月。[RFC6749] 和OAuth 2.0 承载令牌使用Jones, M. 和 D. Hardt,“OAuth 2.0 授权框架:不记名令牌的使用”,2012 年 10 月。[RFC6750] 规范为第三方应用程序获取和使用对 HTTP 资源的有限访问提供了通用框架。他们定义了获取和使用访问令牌来访问资源的机制,但没有定义提供身份信息的标准方法。值得注意的是,如果不分析 OAuth 2.0,它就无法提供有关最终用户身份验证的信息。读者应该熟悉这些规范。

OpenID Connect 将身份验证作为 OAuth 2.0 授权流程的扩展来实现。客户端通过在授权请求中包含openid范围值来请求使用此扩展。有关所执行身份验证的信息以JSON Web 令牌 (JWT)Jones, M.、Bradley, J. 和 N. Sakimura,“JSON Web 令牌 (JWT)”,2015 年 5 月。 [JWT]形式返回,称为 ID 令牌(请参阅第 2 节身份令牌)。实现 OpenID Connect 的 OAuth 2.0 身份验证服务器也称为 OpenID 提供商 (OP)。使用 OpenID Connect 的 OAuth 2.0 客户端也称为依赖方 (RP)。

本规范假设依赖方已获得有关 OpenID 提供者的配置信息,包括其授权端点和令牌端点位置。此信息通常通过 Discovery 获取,如OpenID Connect Discovery 1.0Sakimura, N.、Bradley, J.、Jones, M. 和 E. Jay,“OpenID Connect Discovery 1.0”,2023 年 12 月。 [OpenID.Discovery] 中所述,或者可以通过其他机制获取。

同样,本规范假设依赖方已获得足够的凭据并提供了使用 OpenID 提供程序所需的信息。这通常通过动态注册完成,如 OpenID Connect 动态客户端注册 1.0Sakimura, N.、Bradley, J. 和 M. Jones,“OpenID Connect 动态客户端注册 1.0”,2023 年 12 月。 [OpenID.Registration] 中所述,或者可以通过其他机制获得。

该规范的先前版本是:



目录

1.1.需求符号和约定

关键词“必须”、“不得”、“必需”、“应”、“不应”、“应该”、“不应该”、“推荐”、“不推荐”、“可以”和“可选”本文档中的“应按照RFC 2119Bradner, S.,“RFC 中用于指示需求级别的关键词”,1997 年 3 月。 [RFC2119] 中的描述进行解释。

在本规范的 .txt 版本中,引用值表明它们应按字面意思理解。在协议消息中使用这些值时,不得将引号用作值的一部分。在本规范的 HTML 版本中,按字面意思取值是通过使用这种固定宽度字体来指示的。

本规范中JSON Web 签名 (JWS)Jones, M.、Bradley, J. 和 N. Sakimura,“JSON Web 签名 (JWS)”,2015 年 5 月。 [JWS] 和JSON Web 加密 (JWE)Jones, M. 和 J. Hildebrand,“JSON Web 加密 (JWE)”,2015 年 5 月。 [JWE] 数据结构 的所有使用均利用 JWS 紧凑序列化或 JWE 紧凑序列化;不使用 JWS JSON 序列化和 JWE JSON 序列化。



目录

1.2.术语

本规范使用术语“访问令牌”、“授权代码”、“授权端点”、“授权授予”、“授权服务器”、“客户端”、“客户端身份验证”、“客户端标识符”、“客户端密钥”、“ OAuth 2.0Hardt, D., Ed.,“OAuth 2.0 授权框架”,2012 年 10 月。 [RFC6749]定义的“授权类型”、“受保护资源”、“重定向 URI”、“刷新令牌”、“资源服务器”、“响应类型”和“令牌端点”,术语“声明名称”、“声明值”、“JSON Web 令牌 (JWT)”、“JWT 声明集”和由JSON Web 令牌 (JWT)Jones, M.、Bradley, J. 和 N. Sakimura,“JSON Web 令牌 (JWT)”,2015 年 5 月。 [JWT] 定义的“嵌套 JWT”,术语“Base64url 编码”、“标头参数”和“ JSON Web 签名 (JWS)Jones, M.、Bradley, J. 和 N. Sakimura,“JSON Web 签名 (JWS)”,2015 年 5 月。 [JWS]定义的“JOSE 标头” 、 RFC 7230Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing,” June 2014.) [RFC7230]定义的术语“用户代理”以及OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses]定义的术语“响应模式”

本规范还定义了以下术语:

验证
用于对实体和所呈现的身份之间的绑定实现足够的信任的过程。
认证请求
OAuth 2.0 授权请求使用 OpenID Connect 定义的扩展参数和范围来请求授权服务器(OpenID Connect 提供者)向客户端(OpenID Connect 依赖方)对最终用户进行身份验证。
认证上下文
依赖方在针对身份验证响应做出权利决定之前可以要求的信息。此类上下文可以包括但不限于所使用的实际身份验证方法或保证级别,例如 ISO/IEC 29115 (International Organization for Standardization, “ISO/IEC 29115:2013. Information technology - Security techniques - Entity authentication assurance framework,” April 2013.) [ISO29115] 实体身份验证保证级别。
认证上下文类
在特定上下文中被认为彼此等效的一组身份验证方法或过程。
身份验证上下文类参考
身份验证上下文类的标识符。
授权码流程
OAuth 2.0 流程,其中从授权端点返回授权代码,并且从令牌端点返回所有令牌。
授权请求
[RFC6749] (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) 定义的 OAuth 2.0 授权请求
宣称
断言有关实体的信息。
声明类型
用于表示声明值的语法。该规范定义了普通、聚合和分布式声明类型。
理赔提供者
可以返回有关实体的声明的服务器。
凭据
作为使用身份或其他资源的权利证据提供的数据。
最终用户
人类参与者。
实体
具有独立且独特的存在并且可以在上下文中识别的东西。最终用户是实体的一个示例。
基本声明
客户指定的声明是确保最终用户请求的特定任务顺利授权体验所必需的。
混合流
OAuth 2.0 流程,其中从授权端点返回授权代码,从授权端点返回一些令牌,从令牌端点返回其他令牌。
身份令牌
JSON Web 令牌 (JWT) (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.) [JWT],包含有关身份验证事件的声明。它可能包含其他声明。
标识符
在特定上下文中唯一表征实体的值。
身份
与实体相关的属性集。
隐式流程
OAuth 2.0 流程,其中所有令牌均从授权端点返回,并且既不使用令牌端点也不使用授权代码。
发行人
发出一组声明的实体。
发行人标识符
发行人的可验证标识符。颁发者标识符是使用https方案的区分大小写的 URL,其中包含方案、主机以及可选的端口号和路径组件,但不包含查询或片段组件。
信息
OpenID 依赖方和 OpenID 提供商之间的请求或响应。
OpenID 提供商 (OP)
OAuth 2.0 授权服务器能够对最终用户进行身份验证并向依赖方提供有关身份验证事件和最终用户的声明。
请求对象
JWT 包含一组请求参数作为其声明。
请求URI
引用包含请求对象的资源的 URL。请求 URI 内容必须可由授权服务器检索。
成对假名标识符 (PPID)
向依赖方标识实体的标识符,该标识符无法与另一个依赖方的实体的 PPID 相关联。
个人身份信息 (PII)
(a) 可用于识别与该信息相关的自然人的信息,或者 (b) 是或可能与与该信息相关的自然人直接或间接相关的信息。
依赖方 (RP)
OAuth 2.0 客户端应用程序需要来自 OpenID 提供商的最终用户身份验证和声明。
扇区标识符
依赖方组织使用的 URL 的主机组件,是该依赖方成对主题标识符计算的输入。
自发行 OpenID 提供商
颁发自签名 ID 令牌的个人自托管 OpenID 提供商。
主题标识符
最终用户的发行者内部本地唯一且从未重新分配的标识符,旨在由客户端使用。
用户信息端点
受保护的资源,当客户端提供访问令牌时,返回有关由相应授权授予代表的最终用户的授权信息。 UserInfo 端点 URL 必须使用https方案,并且可以包含端口、路径和查询参数组件。
验证
旨在确定结构的健全性或正确性的过程。
确认
旨在测试或证明事实或值的真实性或准确性的过程。
自愿声明
客户指定的声明对最终用户请求的特定任务有用但不是必需的。

读者重要提示:本节中的术语定义是本规范的规范部分,对实现提出了要求。本规范文本中的所有大写单词(例如“发行者标识符”)均引用这些定义的术语。每当读者遇到它们时,都必须遵循本节中的定义。

有关某些术语的更多背景信息,请参阅《互联网安全术语表》第 2 版 (Shirey, R., “Internet Security Glossary, Version 2,” August 2007.)[RFC4949]、 ISO/IEC 29115 实体身份验证保证 (International Organization for Standardization, “ISO/IEC 29115:2013. Information technology - Security techniques - Entity authentication assurance framework,” April 2013.)[ISO29115] 和ITU-T X.1252 (International Telecommunication Union, “ITU-T Recommendation X.1252 - Cyberspace security - Identity management - Baseline identity management terms and definitions,” April 2010.) [X.1252]。



目录

1.3.概述

OpenID Connect 协议抽象地遵循以下步骤。

  1. RP(客户端)向 OpenID 提供商(OP)发送请求。
  2. OP 对最终用户进行身份验证并获得授权。
  3. OP 使用 ID 令牌(通常是访问令牌)进行响应。
  4. RP 可以将带有访问令牌的请求发送到 UserInfo 端点。
  5. UserInfo 端点返回有关最终用户的声明。

这些步骤如下图所示:

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


目录

2. ID令牌

OpenID Connect 对 OAuth 2.0 进行的主要扩展是 ID 令牌数据结构,以使最终用户能够进行身份验证。 ID 令牌是一种安全令牌,包含有关使用客户端时授权服务器对最终用户进行身份验证的声明,以及可能的其他请求的声明。 ID 令牌表示为 JSON Web 令牌 (JWT) (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.) [JWT]。

以下声明在 OpenID Connect 使用的所有 OAuth 2.0 流的 ID 令牌中使用:

国际空间站
必需的。响应的发行者的发行者标识符。 iss值是一个区分大小写的 URL,使用https方案,其中包含方案、主机以及可选的端口号和路径组件,但不包含查询或片段组件。
必需的。主题标识符。最终用户的发行者内本地唯一且永不重新分配的标识符,旨在由客户端使用,例如24400320AItOawmwtWwcT0k51BayewNvutrJUqsvl6qs7A4。它的长度不得超过 255 个 ASCII [RFC20]字符。 (Cerf, V., “ASCII format for Network Interchange,” October 1969.)sub是区分大小写的字符串。
音频
必需的。此 ID 令牌的目标受众。它必须包含 依赖方的OAuth 2.0 client_id作为受众值。它还可以包含其他受众的标识符。一般情况下,aud值是一个区分大小写的字符串数组。在有一个观众的常见特殊情况下,aud值可以是单个区分大小写的字符串。
经验值
必需的。到期时间,在该时间或之后,在与 OP 执行身份验证时,RP 不得接受 ID 令牌。处理此参数要求当前日期/时间必须早于值中列出的到期日期/时间。实施者可以提供一些小的余地,通常不超过几分钟,以解决时钟偏差。它的值是一个 JSON [RFC8259] (Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format,” December 2017.)数字,表示从 1970-01-01T00:00:00Z(以 UTC 测量)到日期/时间的秒数。有关一般日期/时间(特别是 UTC)的详细信息,请参阅RFC 3339 (Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps,” July 2002.) [RFC3339]。注意:ID 令牌过期时间与 RP 和 OP 之间经过身份验证的会话的生命周期无关。
我在
必需的。 JWT 的发布时间。它的值是一个 JSON 数字,表示从 1970-01-01T00:00:00Z(以 UTC 测量)到该日期/时间的秒数。
验证时间
最终用户身份验证发生的时间。它的值是一个 JSON 数字,表示从 1970-01-01T00:00:00Z(以 UTC 测量)到该日期/时间的秒数。当发出max_age请求或请求auth_time作为基本声明时,则此声明是必需的;否则,其包含是可选的。 (auth_time Claim 在语义上对应于 OpenID 2.0 PAPE (Recordon, D., Jones, M., Bufu, J., Ed., Daugherty, J., Ed., and N. Sakimura, “OpenID Provider Authentication Policy Extension 1.0,” December 2008.) [OpenID.PAPE] auth_time响应参数。)
随机数
用于将客户端会话与 ID 令牌相关联并减轻重放攻击的字符串值。该值未经修改地从身份验证请求传递到 ID 令牌。如果 ID 令牌中存在,则客户端必须验证随机数声明值是否等于 身份验证请求中发送的随机数参数的值。如果出现在身份验证请求中,授权服务器必须在 ID 令牌中包含一个随机数声明,该声明值是身份验证请求中发送的随机数值。授权服务器不应该对使用的随机数值执行其他处理。nonce是区分大小写的字符串。
丙烯酰胺
选修的。身份验证上下文类参考。指定身份验证上下文类参考值的字符串,该值标识执行的身份验证所满足的身份验证上下文类。值“0”表示最终用户身份验证不符合 ISO/IEC 29115 (International Organization for Standardization, “ISO/IEC 29115:2013. Information technology - Security techniques - Entity authentication assurance framework,” April 2013.) [ISO29115] 1 级的要求。由于历史原因,值“0”用于表示不确信同一个人是同一个人。实际上在那里。级别 0 的身份验证不应用于授权对任何货币价值的任何资源的访问。 (这对应于 OpenID 2.0 PAPE (Recordon, D., Jones, M., Bufu, J., Ed., Daugherty, J., Ed., and N. Sakimura, “OpenID Provider Authentication Policy Extension 1.0,” December 2008.) [OpenID.PAPE] nist_auth_level 0.)绝对 URI 或RFC 6711 (Johansson, L., “An IANA Registry for Level of Assurance (LoA) Profiles,” August 2012.) [RFC6711] 注册名称应该用作acr值;注册名称不得以与注册名称不同的含义使用。使用此声明的各方需要就所使用的值的含义达成一致,这可能是特定于上下文的。acr是区分大小写的字符串。
阿姆鲁
选修的。身份验证方法参考。 JSON 字符串数组,是身份验证中使用的身份验证方法的标识符。例如,值可能表明同时使用了密码和 OTP 身份验证方法。amr是区分大小写的字符串数组。amr声明中使用的值 应来自在[RFC8176] 建立的IANA 身份验证方法参考值注册表[IANA.AMR] (IANA, “Authentication Method Reference Values,” .)中注册的值;使用此声明的各方需要就所使用的任何未注册值的含义达成一致,这可能是特定于上下文的。 (Jones, M., Hunt, P., and A. Nadalin, “Authentication Method Reference Values,” June 2017.)
氮杂蛋白
选修的。授权方 - ID 令牌的颁发方。如果存在,它必须包含该方的 OAuth 2.0 客户端 ID。azp是包含 StringOrURI 值的区分大小写的字符串。请注意,实际上,azp声明仅在使用超出本规范范围的扩展时出现;因此,鼓励不使用此类扩展的实现不要使用azp ,并在它发生时忽略它。

ID 令牌可能包含其他声明。任何不被理解的声明都必须被忽略。 有关本规范定义的附加声明, 参阅 3.1.3.6、3.3.2.11、5.1 (ID Token)7.4 (ID Token) (Standard Claims) (Self-Issued OpenID Provider Response)

ID 令牌必须使用JWS [JWS] 进行签名,并且可选地分别使用 (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.)JWS (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.) [JWS] 和JWE (Jones, M. and J. Hildebrand, “JSON Web Encryption (JWE),” May 2015.) [JWE]进行签名和加密,从而根据第 16.14 节 (Signing and Encryption Order)提供身份验证、完整性、不可否认性和可选的机密性。如果 ID 令牌已加密,则必须对其进行签名然后加密,结果是嵌套 JWT,如[JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)中所定义。 ID 令牌不得使用none 作为alg值,除非使用的响应类型未从授权端点返回任何 ID 令牌(例如使用授权代码流时)并且客户端在注册时 明确请求使用 none 。

ID 令牌不应使用 JWS 或 JWE x5ux5cjkujwk 标头参数字段。相反,根据第 10 节 (Signatures and Encryption),使用发现和注册参数提前传达对所使用密钥的引用

以下是 ID 令牌中的声明集(JWT 声明集)的非规范示例:

  {
   "iss": "https://server.example.com",
   "sub": "24400320",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "auth_time": 1311280969,
   "acr": "urn:mace:incommon:iap:silver"
  }


目录

3. 认证

OpenID Connect 执行身份验证以登录最终用户或确定最终用户已登录。OpenID Connect 将服务器执行的身份验证结果以安全的方式返回给客户端,以便客户端可以信赖它。因此,在这种情况下,客户端称为依赖方 (RP)。

身份验证结果以 ID 令牌形式返回,如第 2 节 (ID Token)中所定义。它有声明,表达诸如发行者、主题标识符、执行身份验证的时间等信息。

身份验证可以遵循以下三种路径之一:授权代码流 ( response_type=code )、隐式流(response_type=id_token tokenresponse_type=id_token)或混合流(使用 OAuth 2.0 多重响应类型编码中定义的其他响应类型值)实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses])。这些流程确定如何将 ID 令牌和访问令牌返回给客户端。

下面的非规范表总结了这三种流程的特征。该表旨在提供一些关于在特定情况下选择哪种流程的指导。



属性 授权码流程 隐式流程 混合流程
所有令牌从授权端点返回
所有令牌从令牌端点返回
令牌不向用户代理公开
客户端可以进行身份验证
可能有刷新令牌
一次往返通信
大部分通信为服务器到服务器通信 变化不定

 OpenID Connect 身份验证流程 

使用的流程由授权请求中包含的response_type值 确定。这些response_type值选择这些流:



“响应类型”值 授權類型
code 授权码流程
id_token  隐式流程
id_token token  隐式流程
code id_token  混合流
code token  混合流
code id_token token 混合流

 OpenID Connect“response_type”值 

除OAuth 2.0 [RFC6749]定义的代码响应类型值 外,所有其他值均在OAuth 2.0 多重响应类型编码实践[OAuth.Responses] 规范中定义 。注意:虽然 OAuth 2.0 还定义了 隐式流的令牌响应类型值,但 OpenID Connect 不使用此响应类型,因为不会返回 ID 令牌。 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)



目录

3.1.使用授权码流程进行身份验证

本节介绍如何使用授权代码流程执行身份验证。使用授权代码流时,所有令牌均从令牌端点返回。

授权代码流程将授权代码返回给客户端,然后客户端可以直接将其交换为 ID 令牌和访问令牌。这样做的好处是不会向用户代理以及可能访问用户代理的其他恶意应用程序暴露任何令牌。授权服务器还可以在将授权代码交换为访问令牌之前对客户端进行身份验证。授权代码流程适用于可以在自己和授权服务器之间安全维护客户端密钥的客户端。



目录

3.1.1.授权码流程步骤

授权代码流程经历以下步骤。

  1. 客户端准备包含所需请求参数的身份验证请求。
  2. 客户端将请求发送到授权服务器。
  3. 授权服务器对最终用户进行身份验证。
  4. 授权服务器获得最终用户同意/授权。
  5. 授权服务器将最终用户连同授权代码发送回客户端。
  6. 客户端使用令牌端点处的授权代码请求响应。
  7. 客户端收到响应正文中包含 ID 令牌和访问令牌的响应。
  8. 客户端验证 ID 令牌并检索最终用户的主题标识符。



目录

3.1.2.授权端点

授权端点执行最终用户的身份验证。这是通过使用 OAuth 2.0 定义的请求参数以及 OpenID Connect 定义的附加参数和参数值将用户代理发送到授权服务器的授权端点进行身份验证和授权来完成的。

与授权端点的通信必须使用 TLS。有关使用 TLS 的更多信息, 请参阅第 16.17 节。 (TLS Requirements)



目录

3.1.2.1.认证请求

身份验证请求是 OAuth 2.0 授权请求,请求授权服务器对最终用户进行身份验证。

授权服务器必须支持在授权端点使用RFC 7231 [RFC7231]中定义的HTTP GETPOST方法。客户端可以使用 HTTP GETPOST方法将授权请求发送到授权服务器。如果使用 HTTP GET方法,则根据第 13.1 节,使用 URI 查询字符串序列化来序列化请求参数。如果使用 HTTP POST方法,则根据第 13.2 节 ,使用表单序列化来序列化请求参数 (Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content,” June 2014.) (Query String Serialization) (Form Serialization)

OpenID Connect 将以下 OAuth 2.0 请求参数与授权代码流结合使用:

范围
必需的。 OpenID Connect 请求必须包含openid范围值。如果openid范围值不存在,则行为完全未指定。可能存在其他范围值。实现不能理解的范围值应该被忽略。 有关本规范定义的其他范围值, 请参阅第 5.4 (Requesting Claims using Scope Values)节 和第 11节。 (Offline Access)
响应类型
必需的。 OAuth 2.0 响应类型值,确定要使用的授权处理流程,包括从使用的端点返回哪些参数。使用授权代码流时,该值为 code
客户ID
必需的。 OAuth 2.0 客户端标识符在授权服务器上有效。
重定向URI
必需的。响应将发送到的重定向 URI。该 URI 必须与在 OpenID 提供商处预先注册的客户端的重定向 URI 值之一完全匹配,并按照[RFC3986] (Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax,” January 2005.)(简单字符串比较)第 6.2.1 节中所述执行匹配。使用此流程时,重定向 URI 应使用https方案;但是,它可以使用http方案,前提是客户端类型是 机密的(如 OAuth 2.0 第 2.1 节中定义),并且 OP 允许在这种情况下使用 http重定向 URI。另外,如果客户端是本机应用程序,它可以使用带有 localhost的http方案或 IP 环回文字 127.0.0.1[::1] 作为主机名。重定向 URI 可以使用替代方案,例如旨在识别对本机应用程序的回调的方案。
状态
受到推崇的。用于维护请求和回调之间的状态的不透明值。通常,跨站点请求伪造(CSRF、XSRF)缓解是通过以加密方式将此参数的值与浏览器 cookie 绑定来完成的。

OpenID Connect 还使用以下 OAuth 2.0 请求参数,该参数在 OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses] 中定义:

响应模式
选修的。通知授权服务器用于从授权端点返回参数的机制。当请求的响应模式是为响应类型指定的默认模式时,不建议使用此参数。

该规范还定义了以下请求参数:

随机数
选修的。用于将客户端会话与 ID 令牌相关联并减轻重放攻击的字符串值。该值未经修改地从身份验证请求传递到 ID 令牌。用于防止攻击者猜测值的随机数值中必须存在足够的熵 。有关实施说明,请参阅第 15.5.2 节 (Nonce Implementation Notes)
展示
选修的。指定授权服务器如何向最终用户显示身份验证和同意用户界面页面的 ASCII 字符串值。定义的值为:
授权服务器应该显示与完整用户代理页面视图一致的身份验证和同意 UI。如果不指定显示参数,则这是默认的显示模式。
弹出窗口
授权服务器应该显示与弹出的用户代理窗口一致的身份验证和同意 UI。弹出的用户代理窗口的大小应适合以登录为中心的对话框,并且不应遮盖其弹出的整个窗口。
触碰
授权服务器应该显示与利用触摸界面的设备一致的身份验证和同意 UI。
无线应用程序
授权服务器应该显示与“功能手机”类型显示一致的身份验证和同意 UI。
授权服务器还可以尝试检测用户代理的功能并提供适当的显示。
如果OP接收到一个它不理解的超出上面定义的显示值,它可以返回一个错误或者可以忽略它;实际上,不返回不理解的值的错误将有助于促进使用新 显示值的分阶段扩展。
迅速的
选修的。以空格分隔、区分大小写的 ASCII 字符串值列表,指定授权服务器是否提示最终用户重新进行身份验证并同意。定义的值为:
没有任何
授权服务器不得显示任何身份验证或同意用户界面页面。如果最终用户尚未经过身份验证,或者客户没有对所请求的声明预先配置同意,或者不满足处理请求的其他条件,则会返回错误。错误代码通常是 login_requiredinteraction_required第3.1.2.6节 (Authentication Error Response)中定义的其他代码。这可以用作检查现有身份验证和/或同意的方法。
登录
授权服务器应该提示最终用户重新进行身份验证。如果它无法重新验证最终用户,它必须返回一个错误,通常是login_required
同意
授权服务器应在将信息返回给客户端之前提示最终用户同意。如果它无法获得同意,它必须返回一个错误,通常是consent_required
选择帐户
授权服务器应提示最终用户选择用户帐户。这使得在授权服务器上拥有多个帐户的最终用户能够在他们可能拥有当前会话的多个帐户中进行选择。如果它无法获取最终用户做出的帐户选择选择,它必须返回错误,通常是account_selection_required
客户端可以使用prompt 参数来确保最终用户仍在当前会话中或引起对请求的注意。如果此参数包含none 或任何其他值,则返回错误。
如果 OP 收到上面定义的集合之外的它不理解的提示值,它可以返回错误或可以忽略它;在实践中,不返回不理解的值的错误将有助于促进使用新 提示值的分阶段扩展。
最大年龄
选修的。最大身份验证年龄。指定自上次 OP 主动验证最终用户以来允许的经过时间(以秒为单位)。如果经过的时间大于此值,OP 必须尝试主动重新验证最终用户。 (max_age请求参数对应于 OpenID 2.0 PAPE (Recordon, D., Jones, M., Bufu, J., Ed., Daugherty, J., Ed., and N. Sakimura, “OpenID Provider Authentication Policy Extension 1.0,” December 2008.) [OpenID.PAPE] max_auth_age请求参数。)当使用max_age时,返回的 ID 令牌必须包含auth_time声明值。请注意,max_age=0相当于Prompt=login
用户界面区域设置
选修的。最终用户的用户界面首选语言和脚本,表示为以空格分隔的 BCP47 (Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages,” September 2009.) [RFC5646] 语言标签值列表,按首选项排序。例如,值“fr-CA fr en”表示优先选择在加拿大使用的法语,然后是法语(没有地区指定),最后是英语(没有地区指定)。如果 OpenID 提供者不支持部分或全部请求的语言环境,则不应产生错误。
id_token_hint
选修的。授权服务器先前颁发的 ID 令牌作为有关最终用户当前或过去与客户端进行身份验证的会话的提示进行传递。如果 ID 令牌标识的最终用户已经登录或作为请求的结果登录(OP 可能在此决策中评估 ID 令牌之外的其他信息),则授权服务器返回肯定响应;否则,它必须返回错误,例如login_required。如果可能的话,当使用prompt=none 时,应该存在id_token_hint ,如果不存在,可能会返回invalid_request错误;然而,服务器应该尽可能成功响应,即使它不存在。当授权服务器用作 id_token_hint值时,无需将其列为 ID 令牌的受众。
如果 RP 从 OP 接收到的 ID 令牌是加密的,要将其用作 id_token_hint 客户端必须解密加密的 ID 令牌中包含的签名 ID 令牌。客户端可以使用密钥重新加密发送给身份验证服务器的签名 ID 令牌,该密钥使服务器能够解密 ID 令牌并使用重新加密的 ID 令牌作为 id_token_hint值。
登录提示
选修的。向授权服务器提示最终用户可能用于登录的登录标识符(如有必要)。如果 RP 首先向最终用户询问其电子邮件地址(或其他标识符),然后希望将该值作为提示传递给发现的授权服务,则可以使用此提示。建议提示值与用于发现的值匹配。该值也可以是为phone_number声明指定的格式的电话号码 。该参数的使用由 OP 自行决定。
acr_值
选修的。请求的身份验证上下文类参考值。以空格分隔的字符串,指定 请求授权服务器用于处理此身份验证请求的acr值,这些值按优先顺序显示。所执行的身份验证所满足的身份验证上下文类作为acr声明值返回,如第 2 节 (ID Token)中所指定。 acr Claim 是通过参数作为自愿声明请求的。

可以发送其他参数。 有关本规范定义的其他授权请求参数和参数值, 请参阅第3.2.2 (Authorization Endpoint)3.3.2 (Authorization Endpoint)5.2 (Claims Languages and Scripts)5.5 (Requesting Claims using the "claims" Request Parameter)6 (Passing Request Parameters as JWTs)7.2.1 (Providing Information with the "registration" Request Parameter)节。

以下是客户端的非规范示例 HTTP 302 重定向响应,它触发用户代理向授权端点发出身份验证请求(值内换行仅用于显示目的):

  HTTP/1.1 302 Found
  Location: https://server.example.com/authorize?
    response_type=code
    &scope=openid%20profile%20email
    &client_id=s6BhdRkqt3
    &state=af0ifjsldkj
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb

以下是非规范示例请求,该请求将由用户代理发送到授权服务器,以响应上述客户端的 HTTP 302 重定向响应(值内换行仅用于显示目的):

  GET /authorize?
    response_type=code
    &scope=openid%20profile%20email
    &client_id=s6BhdRkqt3
    &state=af0ifjsldkj
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
  Host: server.example.com


目录

3.1.2.2. 身份验证请求验证

授权服务器必须验证收到的请求,如下所示:

  1. 授权服务器必须根据 OAuth 2.0 规范验证所有 OAuth 2.0 参数。
  2. 验证范围参数是否存在并且包含openid范围值。 (如果不存在openid范围值,则该请求可能仍然是有效的 OAuth 2.0 请求,但不是 OpenID Connect 请求。)
  3. 授权服务器必须验证所有必需的参数都存在并且它们的使用符合本规范。
  4. 如果使用 ID 令牌的特定值请求子(主题)声明,则仅当该值标识的最终用户与授权服务器有活动会话或已被身份验证时,授权服务器才必须发送肯定响应请求的结果。授权服务器不得回复其他用户的 ID 令牌或访问令牌,即使他们与授权服务器有活动会话。如果实现支持 声明参数,则可以使用id_token_hint参数或通过请求第 5.5.1 节 (Individual Claims Requests)中所述的特定声明值来发出此类请求 。
  5. id_token_hint存在时,OP 必须验证它是 ID 令牌的发行者。当 ID 令牌标识的 RP 在 OP 上有当前会话或最近的会话时,OP 应该接受 ID 令牌,即使exp时间已经过去。

正如OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 中所指定的,授权服务器应该忽略无法识别的请求参数。

如果授权服务器遇到任何错误,它必须根据第 3.1.2.6 节 (Authentication Error Response)返回错误响应。



目录

3.1.2.3.授权服务器对最终用户进行身份验证

如果请求有效,授权服务器将尝试对最终用户进行身份验证或确定最终用户是否已通过身份验证,具体取决于所使用的请求参数值。授权服务器用于验证最终用户的方法(例如,用户名和密码、会话cookie 等)超出了本规范的范围。授权服务器可以显示身份验证用户界面,具体取决于所使用的请求参数值和所使用的身份验证方法。

在以下情况下,授权服务器必须尝试对最终用户进行身份验证:

在以下情况下,授权服务器不得与最终用户交互:

与最终用户交互时,授权服务器必须采用适当的措施来防止跨站点请求伪造和点击劫持,如OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 的第 10.12 和 10.13 节中所述。



目录

3.1.2.4.授权服务器获取最终用户同意/授权

一旦最终用户通过身份验证,授权服务器必须在向依赖方发布信息之前获得授权决定。当所使用的请求参数允许时,这可以通过与最终用户的互动对话来完成,明确同意什么,或者通过处理请求的条件或其他方式(例如,通过先前的管理)建立同意。同意)。第2 (ID Token)第5.3 (UserInfo Endpoint)节描述了信息发布机制。



目录

3.1.2.5.认证成功响应

身份验证响应是从 OP 的授权端点返回的 OAuth 2.0 授权响应消息,以响应 RP 发送的授权请求消息。

当使用授权代码流时,授权响应必须返回OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 4.1.2 节中定义的参数,方法是 将它们作为查询参数添加到 使用application/x-www-form- 的授权请求中指定的redirect_uri urlencoded格式,除非指定了不同的响应模式。

以下是使用此流程的成功响应的非规范示例(仅出于显示目的在值内换行):

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb?
    error=invalid_request
    &error_description=
      Unsupported%20response_type%20value
    &state=af0ifjsldkj

有关授权代码内容的实施说明,请参阅第 15.5.1 节 (Authorization Code Implementation Notes)



目录

3.1.2.6.认证错误响应

身份验证错误响应是从 OP 的授权端点返回的 OAuth 2.0 授权错误响应消息,以响应 RP 发送的授权请求消息。

如果最终用户拒绝请求或最终用户身份验证失败,OP(授权服务器)将使用OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 4.1.2.1 节中定义的错误响应参数通知 RP(客户端)。 (与 RFC 6749 无关的 HTTP 错误将使用适当的 HTTP 状态代码返回给用户代理。)

除非重定向 URI 无效,否则授权服务器将客户端返回到授权请求中指定的重定向 URI,并带有适当的错误和状态参数。其他参数不应返回。如果重定向 URI 无效,授权服务器不得将用户代理重定向到无效的重定向 URI。

如果不支持响应模式值,则授权服务器将返回 HTTP 响应代码 400(错误请求),且不带错误响应参数,因为需要了解响应模式才能知道如何返回这些参数。

除了OAuth 2.0第4.1.2.1节中定义的错误代码之外,本规范还定义了以下错误代码:

需要交互
授权服务器需要某种形式的最终用户交互才能继续。当身份验证请求中的提示参数值为none时,可能会返回此错误 ,但如果不显示最终用户交互的用户界面,则无法完成身份验证请求。
要求登录
授权服务器需要最终用户身份验证。当身份验证请求中的提示参数值为none时,可能会返回此错误 ,但如果不显示最终用户身份验证的用户界面,则无法完成身份验证请求。
account_selection_required
最终用户需要在授权服务器上选择一个会话。最终用户可以在授权服务器上使用不同的关联帐户进行身份验证,但最终用户未选择会话。当身份验证请求中的提示参数值为none时,可能会返回此错误,但如果不显示用户界面来提示要使用的会话,则无法完成身份验证请求。
需要同意
授权服务器需要最终用户同意。当身份验证请求中的提示参数值为none时,可能会返回此错误 ,但如果不显示最终用户同意的用户界面,则无法完成身份验证请求。
无效的请求URI
授权请求中的request_uri 返回 错误或包含无效数据。
无效请求对象
请求 参数 包含无效的请求对象。
请求不支持
OP 不支持使用 第 6 节中定义的请求参数。 (Passing Request Parameters as JWTs)
request_uri_not_supported
OP 不支持使用 第 6 节中定义的request_uri参数。 (Passing Request Parameters as JWTs)
不支持注册
OP 不支持使用 第 7.2.1 节中定义的注册参数。 (Providing Information with the "registration" Request Parameter)

错误响应参数如下:

错误
必需的。错误代码。
错误描述
选修的。人类可读的 ASCII 编码文本描述错误。
错误_uri
选修的。包含有关错误的附加信息的网页的 URI。
状态
OAuth 2.0 状态值。如果授权请求包含状态参数,则为必需。设置为从客户端收到的值。

使用授权代码流时,错误响应参数将添加到重定向 URI 的查询组件中,除非指定了不同的响应模式。

以下是使用此流程的非规范示例错误响应(值内换行仅用于显示目的):

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb?
    error=invalid_request
    &error_description=
      Unsupported%20response_type%20value
    &state=af0ifjsldkj


目录

3.1.2.7.认证响应验证

使用授权代码流程时,客户端必须根据 RFC 6749 验证响应,尤其是第 4.1.2 节和第 10.12 节。



目录

3.1.3.令牌端点

为了获取访问令牌、ID 令牌和可选的刷新令牌,RP(客户端) (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.)使用授权代码流程。

与令牌端点的通信必须使用 TLS。有关使用 TLS 的更多信息, 请参阅第 16.17 节。 (TLS Requirements)



目录

3.1.3.1.令牌请求

客户端通过使用grant_typeauthorization_code 向令牌端点提供其授权授予(以授权代码的形式)来发出令牌请求,如OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 的第 4.1.3 节中所述。如果客户端是机密客户端,则它必须使用为其client_id注册的身份验证方法向令牌端点进行身份验证,如第 9 节 (Client Authentication)中所述。

客户端根据第 13.2 节,使用 HTTP POST方法和表单序列化 将参数发送到令牌端点,如 OAuth 2.0 [RFC6749] 的第 4.1.3 节中所述。 (Form Serialization) (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.)

以下是令牌请求的非规范示例(值内换行仅用于显示目的):

  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded
  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

  grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb


目录

3.1.3.2.令牌请求验证

授权服务器必须按如下方式验证令牌请求:



目录

3.1.3.3.成功的令牌响应

在接收并验证来自客户端的有效且授权的令牌请求后,授权服务器返回包含 ID 令牌和访问令牌的成功响应。成功响应中的参数在OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749]的第 4.1.4 节中定义。响应使用application/json 媒体类型。

OAuth 2.0 token_type响应参数值必须是Bearer,如OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750] 中所指定,除非已与客户端协商了另一个令牌类型。服务器应该支持承载令牌类型;使用其他令牌类型超出了本规范的范围。请注意,token_type值不区分大小写。

除了 OAuth 2.0 指定的响应参数之外,响应中还必须包含以下参数:

id_token
与经过身份验证的会话关联的 ID 令牌值。

所有包含令牌、秘密或其他敏感信息的令牌响应必须包含以下 HTTP 响应标头字段和值:



标头名称标头值
Cache-Control no-store

 HTTP 响应标头和值 

以下是成功令牌响应的非规范示例。示例中的 ID Token 签名可以使用 附录 A.7 (RSA Key Used in Examples)中的密钥进行验证。

  HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store

  {
   "access_token": "SlAV32hkKG",
   "token_type": "Bearer",
   "refresh_token": "8xLOxBtZp8",
   "expires_in": 3600,
   "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
     yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5
     NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ
     fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz
     AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q
     Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ
     NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd
     QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS
     K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4
     XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"
  }

正如OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 中所指定的,客户端应该忽略无法识别的响应参数。



目录

3.1.3.4.令牌错误响应

如果令牌请求无效或未经授权,授权服务器将构造错误响应。令牌错误响应的参数在OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749]的第 5.2 节中定义。 HTTP 响应正文使用application/json 媒体类型,HTTP 响应代码为 400.

以下是一个非规范的令牌错误响应示例:

  HTTP/1.1 400 Bad Request
  Content-Type: application/json
  Cache-Control: no-store

  {
   "error": "invalid_request"
  }


目录

3.1.3.5.令牌响应验证

客户端必须按如下方式验证令牌响应:

  1. 遵循 RFC 6749 中的验证规则,尤其是第 5.1 和 10.12 节中的验证规则。
  2. 遵循第 3.1.3.7 节 (ID Token Validation) 中的 ID 令牌验证规则
  3. 遵循第 3.1.3.8 节 (Access Token Validation) 中的访问令牌验证规则



目录

3.1.3.6.身份令牌

ID Token 的内容如第 2 节 (ID Token)中所述。使用授权代码流程时,以下 ID 令牌声明的附加要求适用:

at_hash
选修的。访问令牌哈希值。它的值是access_token值的 ASCII 表示的八位字节的散列的最左半部分的 base64url 编码 ,其中使用的散列算法是ID 令牌的 JOSE 标头的alg标头参数中使用的散列算法。例如,如果algRS256,则使用 SHA-256 哈希 access_token值,然后获取最左边的 128 位并对它们进行 base64url 编码。at_hash是区分大小写的字符串。



目录

3.1.3.7. ID令牌验证

客户端必须按以下方式验证令牌响应中的 ID 令牌:

  1. 如果 ID 令牌已加密,请使用客户端在注册期间指定的 OP 用于加密 ID 令牌的密钥和算法对其进行解密。如果在注册时与 OP 协商加密并且 ID 令牌未加密,则 RP 应拒绝它。
  2. OpenID 提供商的颁发者标识符(通常在发现期间获得)必须与iss(颁发者)声明 的值完全匹配 。
  3. 客户必须验证 aud(受众)声明包含在由iss (发行人)声明标识 为受众的发行人处注册的client_id值。 aud (观众)声明可以包含一个具有多个元素的数组如果 ID 令牌未将客户端列为有效受众,或者包含客户端不信任的其他受众,则必须拒绝 ID 令牌。
  4. 如果实现正在使用导致azp(授权方)声明存在的扩展(超出了本规范的范围),则它应该验证这些扩展指定的 azp值。
  5. 此验证可以包括当azp(授权方)声明存在时,客户端应该验证其client_id 是声明值。
  6. 如果通过客户端和令牌端点(在此流程中)之间的直接通信接收 ID 令牌,则 TLS 服务器验证可用于验证颁发者而不是检查令牌签名。客户端必须根据 JWS [JWS] 使用 JWT (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.)alg标头参数中指定的算法验证所有其他 ID 令牌的签名。客户必须使用发行人提供的密钥。
  7. alg值应该是RS256的默认值 或注册期间 客户端在 id_token_signed_response_alg 参数中发送的算法
  8. 如果 JWT alg标头参数使用基于 MAC 的算法,例如 HS256HS384HS512 ,则与aud (受众)声明中包含的 client_id对应的 client_secret的UTF-8 [RFC3629] (Yergeau, F., “UTF-8, a transformation format of ISO 10646,” November 2003.)表示形式的八位位组将用作验证签名的密钥。对于基于 MAC 的算法,如果aud是多值, 则行为未指定。
  9. 当前时间必须早于exp声明 所表示的时间
  10. iat Claim 可用于拒绝距当前时间太远的令牌,从而限制为防止攻击而需要存储的随机数的时间可接受的范围是客户特定的。
  11. 如果在身份验证请求中发送了随机数值,则必须存在随机数声明,并检查其值以验证它是否与身份验证请求中发送的值相同。客户端应该检查重放攻击的随机数值。检测重放攻击的精确方法是客户端特定的。
  12. 如果请求acr声明,客户应检查所主张的声明价值是否适当。acr声明值的含义和处理 超出了本规范的范围。
  13. 如果请求了auth_time声明,无论是通过对此声明的特定请求还是使用max_age参数,客户端应该检查auth_time声明值,如果确定自上次最终用户身份验证以来已经过去了太多时间,则请求重新身份验证。



目录

3.1.3.8.访问令牌验证

使用授权代码流时,如果 ID 令牌包含at_hash声明,则客户端可以使用它以与隐式流相同的方式验证访问令牌(如第 3.2.2.9 节 (Access Token Validation)中定义),但使用 ID 令牌和从令牌端点返回的访问令牌。



目录

3.2.使用隐式流程进行身份验证

本节介绍如何使用隐式流程执行身份验证。使用隐式流程时,所有令牌均从授权端点返回;未使用令牌端点。

隐式流程主要由使用脚本语言在浏览器中实现的客户端使用。访问令牌和 ID 令牌直接返回给客户端,这可能会将它们公开给最终用户和有权访问最终用户的用户代理的应用程序。授权服务器不执行客户端身份验证。



目录

3.2.1.隐式流程步骤

隐式流程遵循以下步骤:

  1. 客户端准备包含所需请求参数的身份验证请求。
  2. 客户端将请求发送到授权服务器。
  3. 授权服务器对最终用户进行身份验证。
  4. 授权服务器获得最终用户同意/授权。
  5. 授权服务器将最终用户连同 ID 令牌以及访问令牌(如果请求)发送回客户端。
  6. 客户端验证 ID 令牌并检索最终用户的主题标识符。



目录

3.2.2.授权端点

使用隐式流程时,授权端点的使用方式与第 3.1.2 节 (Authorization Endpoint)中定义的授权代码流程相同,但本节中指定的差异除外。



目录

3.2.2.1.认证请求

身份验证请求按照第 3.1.2.1 节 (Authentication Request) 中的定义进行,但这些身份验证请求参数的使用方式如下:

响应类型
必需的。 OAuth 2.0 响应类型值,确定要使用的授权处理流程,包括从使用的端点返回哪些参数。当使用隐式流程时,该值为 id_token tokenid_token。这两个值的含义在OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses]中定义 。当值为id_token时,不会返回 Access Token
注意:虽然 OAuth 2.0 还定义了 隐式流的令牌响应类型值,但 OpenID Connect 不使用此响应类型,因为不会返回 ID 令牌。
重定向URI
必需的。响应将发送到的重定向 URI。该 URI 必须与在 OpenID 提供商处预先注册的客户端的重定向 URI 值之一完全匹配,并按照[RFC3986] (Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax,” January 2005.)(简单字符串比较)第 6.2.1 节中所述执行匹配。使用此流程时,重定向 URI 不得使用http方案,除非客户端是本机应用程序,在这种情况下,它可以使用带有 localhost或 IP 环回文字 127.0.0.1[::1] 作为主机名的http方案。
随机数
必需的。用于将客户端会话与 ID 令牌相关联并减轻重放攻击的字符串值。该值未经修改地从身份验证请求传递到 ID 令牌。用于防止攻击者猜测值的随机数值中必须存在足够的熵 。有关实施说明,请参阅第 15.5.2 节 (Nonce Implementation Notes)

以下是使用隐式流的非规范示例请求,该请求将由用户代理发送到授权服务器,以响应客户端的相应 HTTP 302 重定向响应(值内换行仅用于显示目的):

  GET /authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj HTTP/1.1
  Host: server.example.com


目录

3.2.2.2.身份验证请求验证

当使用隐式流程时,验证请求的验证方式与授权代码流程相同,如第3.1.2.2 节 (Authentication Request Validation)中所定义。



目录

3.2.2.3.授权服务器对最终用户进行身份验证

使用隐式流程时,最终用户身份验证的执行方式与授权代码流程相同,如第 3.1.2.3 节 (Authorization Server Authenticates End-User)中所定义。



目录

3.2.2.4.授权服务器获取最终用户同意/授权

使用隐式流程时,最终用户同意的获取方式与授权代码流程相同,如第3.1.2.4 节 (Authorization Server Obtains End-User Consent/Authorization)中所定义。



目录

3.2.2.5.认证成功响应

使用隐式流程时,身份验证响应的方式与第 3.1.2.5 节 (Successful Authentication Response)中定义的授权代码流程相同,但本节中指定的差异除外。

使用隐式流时,所有响应参数都将添加到重定向 URI 的片段组件中,如 OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses] 中所指定,除非指定了不同的响应模式。

这些参数从授权端点返回:

访问令牌
OAuth 2.0 访问令牌。除非使用的response_type值为 id_token ,否则将返回此值
令牌类型
OAuth 2.0 令牌类型值。该值必须是Bearer客户端与授权服务器协商的另一个token_type值。实现此配置文件的客户端必须支持OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750] 规范。此配置文件仅描述不记名令牌的使用。这与access_token的返回情况相同
id_token
必需的。 ID 令牌。
状态
OAuth 2.0 状态值。如果 授权请求中存在状态参数,则为必需。客户端必须验证 状态值是否等于授权请求中 状态参数的值。
过期日期在
可选。访问令牌的过期时间(以秒为单位,自响应生成以来)。

根据OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 的第 4.2.2 节,使用隐式流程时不会返回 任何代码结果。

以下是使用隐式流程成功响应的非规范示例(换行仅用于显示目的):

  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


目录

3.2.2.6.认证错误响应

使用隐式流程时,授权错误响应的方式与第 3.1.2.6 节 (Authentication Error Response)中定义的授权代码流程相同,但本节中指定的差异除外。

每当返回错误响应参数时,例如当最终用户拒绝授权或最终用户身份验证失败时,授权服务器必须在重定向 URI 的片段组件中返回错误授权响应,如第 4.2.2.1 节中所定义。 OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 和 OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses],除非指定了不同的响应模式。



目录

3.2.2.7. 重定向 URI 片段处理

由于响应参数是在重定向 URI 片段值中返回的,因此客户端需要让用户代理解析片段编码值并将它们传递给客户端的处理逻辑以供使用。有关 URI 片段处理的实现说明, 请参阅第 15.5.3 节。 (Redirect URI Fragment Handling Implementation Notes)



目录

3.2.2.8.认证响应验证

当使用隐式流程时,客户端必须按如下方式验证响应:

  1. 验证响应是否符合 [OAuth.Responses] (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)第 5 节。
  2. 遵循 RFC 6749 中的验证规则,尤其是第 4.2.2 和 10.12 节中的规则。
  3. 遵循第 3.2.2.11 节 (ID Token Validation) 中的 ID 令牌验证规则
  4. 遵循第 3.2.2.9 节 (Access Token Validation) 中的访问令牌验证规则,除非使用的response_type值为 id_token



目录

3.2.2.9.访问令牌验证

要使用 ID 令牌验证从授权端点颁发的访问令牌,客户端应该执行以下操作:

  1. 使用JWA [JWA] 中为 ID 令牌的 JOSE 标头的alg标头参数 指定的散列算法,对access_token的 ASCII 表示形式的八位位组进行散列。例如,如果algRS256,则使用的哈希算法是 SHA-256. (Jones, M., “JSON Web Algorithms (JWA),” May 2015.)
  2. 获取哈希值的最左半部分并对其进行 base64url 编码。
  3. ID 令牌中at_hash 的值必须与上一步中生成的值匹配。



目录

3.2.2.10.身份令牌

ID Token 的内容如第 2 节 (ID Token)中所述。使用隐式流时,以下 ID 令牌声明的附加要求适用:

随机数
此流程需要 使用随机数声明。
at_hash
访问令牌哈希值。它的值是access_token值的 ASCII 表示的八位字节的散列的最左半部分的 base64url 编码 ,其中使用的散列算法是ID 令牌的 JOSE 标头的alg标头参数中使用的散列算法。例如,如果algRS256,则使用 SHA-256 哈希 access_token值,然后获取最左边的 128 位并对它们进行 base64url 编码。at_hash是区分大小写的字符串。
如果 ID 令牌是从授权端点使用 access_token值发出的( response_typeid_token token就是这种情况),则这是必需的;当没有颁发访问令牌时,不能使用它,response_typeid_token就是这种情况。



目录

3.2.2.11. ID令牌验证

使用隐式流时,必须以与授权代码流相同的方式验证 ID 令牌的内容(如第 3.1.3.7 节 (ID Token Validation)中定义),但本节中指定的差异除外。

  1. 客户端必须使用JOSE 标头的 alg标头参数中指定的算法 根据JWS (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.) [JWS] 验证 ID 令牌的签名 。
  2. 必须检查随机数声明 的值 ,以验证它是否与身份验证请求中发送的值相同。客户端应该检查重放攻击的随机数值。检测重放攻击的精确方法是客户端特定的。



目录

3.3.使用混合流进行身份验证

本节介绍如何使用混合流程执行身份验证。使用混合流时,一些令牌从授权端点返回,其他令牌从令牌端点返回。OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses] 中指定了混合流中返回令牌的机制 。



目录

3.3.1.混合流程步骤

混合流程遵循以下步骤:

  1. 客户端准备包含所需请求参数的身份验证请求。
  2. 客户端将请求发送到授权服务器。
  3. 授权服务器对最终用户进行身份验证。
  4. 授权服务器获得最终用户同意/授权。
  5. 授权服务器将最终用户连同授权代码以及一个或多个附加参数(根据响应类型)发送回客户端。
  6. 客户端使用令牌端点处的授权代码请求响应。
  7. 客户端收到响应正文中包含 ID 令牌和访问令牌的响应。
  8. 客户端验证 ID 令牌并检索最终用户的主题标识符。



目录

3.3.2.授权端点

使用混合流程时,授权端点的使用方式与第 3.1.2 节 (Authorization Endpoint)中定义的授权代码流程相同,但本节中指定的差异除外。



目录

3.3.2.1.认证请求

身份验证请求按照第 3.1.2.1 节 (Authentication Request) 中的定义进行,但这些身份验证请求参数的使用方式如下:

响应类型
必需的。 OAuth 2.0 响应类型值,确定要使用的授权处理流程,包括从使用的端点返回哪些参数。使用混合流时,该值为 code id_tokencode tokencode id_token token。这些值的含义在OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses]中定义
随机数
如果请求的响应类型是code id_tokencode id_token token,则为必需;如果请求的响应类型为code token ,则为可选。它是一个字符串值,用于将客户端会话与 ID 令牌相关联,并减轻重放攻击。该值未经修改地从身份验证请求传递到 ID 令牌。用于防止攻击者猜测值的随机数值中必须存在足够的熵 。有关实施说明,请参阅第 15.5.2 节 (Nonce Implementation Notes)

以下是使用混合流的非规范示例请求,该请求将由用户代理发送到授权服务器,以响应客户端的相应 HTTP 302 重定向响应(值内换行仅用于显示目的):

  GET /authorize?
    response_type=code%20id_token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com


目录

3.3.2.2.身份验证请求验证

使用混合流程时,验证请求的验证方式与授权代码流程相同,如第3.1.2.2 节 (Authentication Request Validation)中所定义。



目录

3.3.2.3.授权服务器对最终用户进行身份验证

使用混合流程时,最终用户身份验证的执行方式与授权代码流程相同,如第3.1.2.3 节 (Authorization Server Authenticates End-User)中所定义。



目录

3.3.2.4.授权服务器获取最终用户同意/授权

使用混合流程时,最终用户同意的获取方式与授权代码流程相同,如第3.1.2.4 节 (Authorization Server Obtains End-User Consent/Authorization)中所定义。



目录

3.3.2.5.认证成功响应

当使用混合流时,认证响应的方式与隐式流相同,如第 3.2.2.5 节 (Successful Authentication Response)中所定义,但本节中指定的差异除外。

这些授权端点结果按以下方式使用:

访问令牌
OAuth 2.0 访问令牌。当使用的response_type值是 code tokencode id_token token时,返回此值。 (在相同情况下也会返回 token_type值。)
id_token
ID 令牌。当使用的response_type值是 code id_tokencode id_token token时返回
代码
授权码。使用混合流时始终会返回此值。

以下是使用混合流成功响应的非规范示例(换行仅用于显示目的):

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


目录

3.3.2.6.认证错误响应

使用混合流程时,授权错误响应的方式与第 3.1.2.6 节 (Authentication Error Response)中定义的授权代码流程相同,但本节中指定的差异除外。

每当返回错误响应参数时,例如当最终用户拒绝授权或最终用户身份验证失败时,授权服务器必须在重定向 URI 的片段组件中返回错误授权响应,如第 4.2.2.1 节中所定义。 OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 和 OAuth 2.0 多重响应类型编码实践 (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)[OAuth.Responses],除非指定了不同的响应模式。



目录

3.3.2.7.重定向 URI 片段处理

使用混合流时,重定向 URI 片段参数处理的要求与隐式流相同,如第 3.2.2.7 节 (Redirect URI Fragment Handling)中所定义。另请参阅第 15.5.3 节 (Redirect URI Fragment Handling Implementation Notes)有关 URI 片段处理的实现说明。



目录

3.3.2.8.认证响应验证

当使用混合流时,客户端必须按如下方式验证响应:

  1. 验证响应是否符合 [OAuth.Responses] (de Medeiros, B., Ed., Scurtescu, M., Tarjan, P., and M. Jones, “OAuth 2.0 Multiple Response Type Encoding Practices,” February 2014.)第 5 节。
  2. 遵循 RFC 6749 中的验证规则,尤其是第 4.2.2 和 10.12 节中的规则。
  3. 当使用的response_type值为 code id_tokencode id_token token时,请遵循第 3.3.2.12 节 (ID Token Validation) 中的 ID 令牌验证规则
  4. 当使用的response_type值为 code tokencode id_token token时,请遵循第 3.3.2.9 节 (Access Token Validation) 中的访问令牌验证规则
  5. 当使用的response_type值为 code id_tokencode id_token token时,请遵循第 3.3.2.10 节 (Authorization Code Validation) 中的授权码验证规则



目录

3.3.2.9.访问令牌验证

使用混合流时,从授权端点返回的访问令牌将以与隐式流相同的方式进行验证,如第 3.2.2.9 节 (Access Token Validation)中所定义。



目录

3.3.2.10.授权码验证

要使用 ID 令牌验证从授权端点发出的授权码,客户端应该执行以下操作:

  1. 使用JWA [JWA] 中为 ID 令牌的 JOSE 标头的alg标头参数 指定的散列算法,对代码的 ASCII 表示形式的八位位组进行散列。例如,如果algRS256,则使用的哈希算法是 SHA-256. (Jones, M., “JSON Web Algorithms (JWA),” May 2015.)
  2. 获取哈希值的最左半部分并对其进行 base64url 编码。
  3. 如果ID 令牌中存在 c_hash ,则 ID 令牌中的c_hash必须与上一步中生成的值匹配。



目录

3.3.2.11.身份令牌

ID Token 的内容如第 2 节 (ID Token)中所述。使用混合流时,以下 ID 令牌声明的附加要求适用于从授权端点返回的 ID 令牌:

随机数
如果身份验证请求中存在随机数参数,则授权服务器必须在 ID 令牌中 包含随机数声明。
at_hash
访问令牌哈希值。它的值是access_token值的 ASCII 表示的八位字节的散列的最左半部分的 base64url 编码 ,其中使用的散列算法是ID 令牌的 JOSE 标头的alg标头参数中使用的散列算法。例如,如果algRS256,则使用 SHA-256 哈希 access_token值,然后获取最左边的 128 位并对它们进行 base64url 编码。at_hash是区分大小写的字符串。
如果 ID 令牌是从授权端点使用 access_token值发出的( response_type代码 id_token token就是这种情况),则这是必需的;否则,其包含是可选的。
c_hash
代码哈希值。它的值是代码值的 ASCII 表示的八位字节的散列的最左半部分的 base64url 编码 ,其中使用的散列算法是ID 令牌的 JOSE 标头的alg标头参数中使用的散列算法。例如,如果algHS512,则 使用 SHA-512 对代码值进行哈希处理,然后获取最左边的 256 位并对它们进行 base64url 编码。c_hash是区分大小写的字符串。
如果 ID 令牌是从授权端点发出的,带有 code , response_typecode id_tokencode id_token token就是这种情况,这是必需的;否则,其包含是可选的。



目录

3.3.2.12. ID令牌验证

当使用混合流时,从授权端点返回的 ID 令牌的内容必须以与隐式流相同的方式进行验证,如第 3.2.2.11 节 (ID Token Validation)中所定义。



目录

3.3.3.令牌端点

使用混合流时,令牌端点的使用方式与第 3.1.3 节 (Token Endpoint)中定义的授权代码流相同,但本节中指定的差异除外。



目录

3.3.3.1.令牌请求

使用混合流程时,令牌请求的发出方式与授权代码流程相同,如第3.1.3.1 节 (Token Request)中所定义。



目录

3.3.3.2.令牌请求验证

使用混合流程时,令牌请求的验证方式与授权代码流程相同,如第3.1.3.2 节 (Token Request Validation)中所定义。



目录

3.3.3.3.成功的令牌响应

使用混合流程时,令牌响应的方式与授权代码流程相同,如第 3.1.3.3 节 (Successful Token Response)中所定义。



目录

3.3.3.4.令牌错误响应

使用混合流程时,令牌错误响应的方式与授权代码流程相同,如第3.1.3.4 节 (Token Error Response)中所定义。



目录

3.3.3.5.令牌响应验证

使用混合流程时,令牌响应的验证方式与授权代码流程相同,如第3.1.3.5 节 (Token Response Validation)中所定义。



目录

3.3.3.6.身份令牌

使用混合流时,从令牌端点返回的 ID 令牌的内容与从授权端点返回的 ID 令牌的内容相同,如第3.3.2.11 节 (ID Token)中所定义,但本节中指定的差异除外。

如果从授权端点和令牌端点都返回了 ID 令牌(response_type代码 id_token代码 id_token token就是这种情况) ,则两个 ID 令牌中的isssub 声明值必须相同。任何一个中存在的有关身份验证事件的所有声明都应该存在于两个中。如果任一 ID 令牌包含有关最终用户的声明,则两者中出现的任何内容都应具有相同的值。请注意,例如,出于隐私原因,OP 可以选择从授权端点返回较少的有关最终用户的声明。 at_hashc_hash声明可以从令牌端点返回的 ID 令牌中省略,即使这些声明存在于从授权端点返回的 ID 令牌中,因为从令牌端点返回的 ID 令牌和访问令牌值已经进行了加密绑定由令牌端点执行的 TLS 加密结合在一起。



目录

3.3.3.7. ID令牌验证

使用混合流时,从令牌端点返回的 ID 令牌的内容必须以与授权代码流相同的方式进行验证,如第 3.1.3.7 节 (ID Token Validation)中所定义。



目录

3.3.3.8.访问令牌

如果从授权端点和令牌端点都返回访问令牌(response_typecode tokencode id_token token就是这种情况),则它们的值可以相同也可以不同。请注意,由于两个端点的安全特性不同,可能会返回不同的访问令牌,并且它们的生命周期和对它们授予的资源的访问权限也可能不同。



目录

3.3.3.9.访问令牌验证

使用混合流时,从令牌端点返回的访问令牌以与授权代码流相同的方式进行验证,如第 3.1.3.8 节 (Access Token Validation)中所定义。



目录

4. 发起第三方登录

在某些情况下,登录流程是由 OpenID 提供商或另一方(而不是依赖方)发起的。在这种情况下,发起者在其登录发起端点重定向到 RP,请求 RP 向指定的 OP 发送身份验证请求。请注意,此登录启动端点可以是 RP 上与 RP 的默认登录页面不同的页面。支持 OpenID Connect 动态客户端注册 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.) [OpenID.Registration] 的 RP 使用 initiate_login_uri注册参数注册此端点值。

发起登录请求的一方通过重定向到 RP 上的登录发起端点并传递以下参数来实现此目的:

国际空间站
必需的。 RP 将向其发送身份验证请求的 OP 的颁发者标识符。它的值必须是使用https方案的URL
登录提示
选修的。向授权服务器提示要进行身份验证的最终用户。这个字符串值参数的含义由OP自行决定。在常见用例中,该值将包含 RP 在向 OP 请求身份验证之前收集的电子邮件地址、电话号码或用户名。例如,RP 在向最终用户询问其电子邮件地址(或其他标识符)后可以使用此提示,将该标识符作为提示传递给 OpenID 提供商。建议提示值与为发现提供的值相匹配。其他用途可以包括使用ID 令牌中的 子声明作为提示值或有关请求的身份验证的潜在其他类型的信息。
目标链接URI
选修的。 RP认证后请求重定向到的URL。 RP 必须验证target_link_uri的值, 以防止被用作外部站点的开放重定向器。

这些参数可以使用 HTTP GET方法 作为查询参数传递,也可以作为在用户代理中自动提交的 HTML 表单值传递,从而通过 HTTP POST方法传输

如果扩展定义了其他参数,则可以发送。客户端必须忽略所使用的任何不理解的参数。

客户应该采用框架破坏和其他技术来防止最终用户在不知情的情况下通过点击劫持等攻击被第三方网站登录。有关更多详细信息, 请参阅[RFC6819]的第 4.4.1.9 节。 (Lodderstedt, T., Ed., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.)



目录

5. 声明

本节指定客户端如何获取有关最终​​用户和身份验证事件的声明。它还定义了一组标准的基本配置文件声明。可以使用特定范围值请求预定义的声明集,也可以使用 声明请求参数请求单个声明。声明可以直接来自 OpenID 提供商,也可以来自分布式来源。



目录

5.1.标准声明

本规范定义了一组标准权利要求。可以请求在 UserInfo 响应(根据第 5.3.2 节 (Successful UserInfo Response))或 ID 令牌(根据第 2 节) (ID Token)中返回它们



成员类型描述
sub 字符串 主题 - 发行人的最终用户的标识符。
name 字符串 可显示形式的最终用户全名,包括所有名称部分,可能包括标题和后缀,根据最终用户的区域设置和偏好排序。
given_name 字符串 最终用户的名字。请注意,在某些文化中,人们可以有多个名字;全部都可以存在,名称之间用空格字符分隔。
family_name 字符串 最终用户的姓氏。请注意,在某些文化中,人们可以有多个姓氏,也可以没有姓氏。全部都可以存在,名称之间用空格字符分隔。
middle_name 字符串 最终用户的中间名。请注意,在某些文化中,人们可以有多个中间名;全部都可以存在,名称之间用空格字符分隔。另请注意,在某些文化中,不使用中间名。
nickname 字符串 最终用户的临时名称可能与 给定名称相同,也可能不同。例如,昵称Mike可能会与给定名称Michael 一起返回
preferred_username 字符串 最终用户希望在 RP 中引用的简写名称,例如 janedoej.doe。该值可以是任何有效的 JSON 字符串,包括特殊字符,例如@/或空格。 RP 不得依赖该值是唯一的,如第 5.7 节 (Claim Stability and Uniqueness)所述。
profile 字符串 最终用户个人资料页面的 URL。该网页的内容应该是关于最终用户的。
picture 字符串 最终用户个人资料图片的 URL。此 URL 必须引用图像文件(例如,PNG、JPEG 或 GIF 图像文件),而不是包含图像的网页。请注意,此 URL 应特别引用适合在描述最终用户时显示的最终用户的个人资料照片,而不是最终用户拍摄的任意照片。
website 字符串 最终用户网页或博客的 URL。该网页应包含最终用户或最终用户所属组织发布的信息。
email 字符串 最终用户的首选电子邮件地址。它的值必须符合RFC 5322 (Resnick, P., Ed., “Internet Message Format,” October 2008.) [RFC5322] addr-spec 语法。 RP 不得依赖该值是唯一的,如第 5.7 节 (Claim Stability and Uniqueness)所述。
email_verified 布尔值 如果最终用户的电子邮件地址已得到验证,则为 True;否则为假。当此声明值为true时,这意味着 OP 采取了积极措施,以确保在执行验证时该电子邮件地址由最终用户控制。验证电子邮件地址的方式是特定于上下文的,并且取决于双方运作的信任框架或合同协议。
gender 字符串 最终用户的性别。本规范定义的值为女性男性。当定义的值都不适用时,可以使用其他值。
birthdate 字符串 最终用户的生日,以 ISO 8601-1 (International Organization for Standardization, “ISO 8601-1:2019/Amd 1:2022. Date and time - Representations for information interchange - Part 1: Basic rules,” October 2022.) [ISO8601-1] YYYY-MM-DD 格式表示。年份可以是0000,表明它被省略。为了仅表示年份,允许使用YYYY格式。请注意,根据底层平台的日期相关功能,仅提供年份可能会导致月份和日期的变化,因此实施者需要考虑此因素以正确处理日期。
zoneinfo 字符串 来自 IANA 时区数据库[IANA.time-zones] (IANA, “Time Zone Database,” .)的字符串 ,表示最终用户的时区。例如,Europe/ParisAmerica/Los_Angeles
locale 字符串 最终用户的区域设置,表示为 BCP47 (Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages,” September 2009.) [RFC5646] 语言标签。这通常是小写的ISO 639 Alpha-2 [ISO639] 语言代码和大写的 (International Organization for Standardization, “ISO 639:2023. Code for individual languages and language groups,” November 2023.)ISO 3166-1 Alpha-2 (International Organization for Standardization, “ISO 3166-1:2020. Codes for the representation of names of countries and their subdivisions - Part 1: Country codes,” August 2020.) [ISO3166-1] 国家/地区代码,并用破折号分隔。例如, en-USfr-CA。作为兼容性说明,某些实现使用下划线而不是破折号作为分隔符,例如 en_US;依赖方也可以选择接受此语言环境语法。
phone_number 字符串 最终用户的首选电话号码。建议采用E.164 (International Telecommunication Union, “E.164: The international public telecommunication numbering plan,” 2010.) [E.164]作为本权利要求的格式,例如+1 (425) 555-1212+56 (2) 687 2400。如果电话号码包含分机号,建议使用 RFC 3966 (Schulzrinne, H., “The tel URI for Telephone Numbers,” December 2004.) [RFC3966] 分机语法表示分机号,例如+1 (604) 555-1234;ext=5678
phone_number_verified 布尔值 如果最终用户的电话号码已得到验证,则为 True;否则为假。当此声明值为true时,这意味着 OP 采取了积极措施,以确保在执行验证时该电话号码由最终用户控制。验证电话号码的方式是特定于上下文的,并且取决于各方运作的信任框架或合同协议。如果为 true,phone_number 声明必须采用 E.164 格式,并且任何分机必须以 RFC 3966 格式表示。
address JSON 对象 最终用户的首选邮政地址。地址成员的值是一个 JSON [RFC8259]结构,包含 (Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format,” December 2017.)第 5.1.1 节 (Address Claim)中定义的部分或全部成员
updated_at 数字 最终用户信息的最后更新时间。它的值是一个 JSON 数字,表示从 1970-01-01T00:00:00Z(以 UTC 测量)到该日期/时间的秒数。

 表 1:注册会员定义 



目录

5.1.1.地址声明

地址声明代表实际邮寄地址。实现可以仅返回地址字段的子集,具体取决于可用信息和最终用户的隐私偏好。例如,可能会返回国家地区,而不返回更细粒度的地址信息。

实现可以仅将完整地址作为格式化子字段中的单个字符串返回,或者它们可以仅返回使用其他子字段的各个组件字段,或者它们可以同时返回两者。如果返回两个变体,它们应该表示相同的地址,格式化的地址指示如何组合组件字段。

下面定义的所有地址值均表示为 JSON 字符串。

格式化的
完整的邮寄地址,格式适合在邮寄标签上显示或使用。该字段可以包含多行,以换行符分隔。换行符可以表示为回车/换行对(“\r\n”)或单个换行符(“\n”)。
街道地址
完整的街道地址组件,可能包括门牌号、街道名称、邮政信箱和多行扩展街道地址信息。该字段可以包含多行,以换行符分隔。换行符可以表示为回车/换行对(“\r\n”)或单个换行符(“\n”)。
地点
城市或地区组成部分。
地区
州、省、地区或地区组成部分。
邮政编码
邮政编码或邮政编码的组成部分。
国家
国家/地区名称组成部分。



目录

5.1.2.额外声明

虽然本说明书仅将一小部分权利要求定义为标准权利要求,但其他权利要求可以与标准权利要求结合使用。使用此类声明时,建议对声明名称使用防冲突名称,如 JSON Web 令牌 (JWT) (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.) [JWT] 规范中所述。或者,当不太可能出现命名冲突时,可以安全地使用私有声明名称,如 JWT 规范中所述。或者,如果特定的附加声明具有广泛且普遍的适用性,则可以根据 JWT 规范使用注册声明名称进行注册。



目录

5.2.权利要求语言和文字

人类可读的声明值和引用人类可读值的声明值可以用多种语言和脚本表示。为了指定语言和脚本,BCP47 (Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages,” September 2009.) [RFC5646] 语言标签被添加到成员名称中,并由#字符分隔。例如, family_name#ja-Kana-JP表示日语中片假名的姓氏,通常用于索引和表示以family_name#ja-Hani-JP表示的相同名称的汉字表示的语音。作为另一个示例,可能会返回websitewebsite#de声明值,引用未指定语言的网站和德语网站。

由于声明名称区分大小写,因此强烈建议声明名称中使用的语言标签值应使用在 IANA“语言子标签注册表” [IANA.Language] (IANA, “Language Subtag Registry,” .) 中注册的字符大小写进行拼写。特别地,通常语言名称用小写字符拼写,区域名称用大写字符拼写,并且脚本用混合大小写字符拼写。然而,由于 BCP47 语言标签值不区分大小写,因此实现应该解释以不区分大小写的方式提供的语言标签值。

根据 BCP47 中的建议,声明的语言标签值应仅根据需要具体化。例如,在许多情况下使用fr可能就足够了,而不是fr-CAfr-FR。在可能的情况下,OP 应该尝试将请求的声明区域设置与其拥有的声明相匹配。例如,如果客户要求带有de(德语)语言标签的声明,并且 OP 具​​有带有de-CH(瑞士德语)标记的值,并且没有通用德语值,则 OP 应该返回瑞士语德国对客户的价值。 (这有意将语言标签匹配的复杂性尽可能转移到 OP,以简化客户端。)

OpenID Connect 定义以下授权请求参数,以指定用于返回声明的首选语言和脚本:

声明_区域设置
选修的。最终用户返回的声明的首选语言和脚本,表示为BCP47 (Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages,” September 2009.) [RFC5646] 语言标签值的空格分隔列表 ,按偏好排序。如果 OpenID 提供者不支持部分或全部请求的语言环境,则不应产生错误。

当OP通过 claims_locales参数或其他方式确定最终用户和客户端仅以一组语言和脚本请求声明时,建议OP在使用该语言时返回不带语言标签的声明和脚本。还建议客户端以可以使用语言标签处理和利用声明的方式编写。



目录

5.3.用户信息端点

UserInfo 端点是受 OAuth 2.0 保护的资源,可返回有关经过身份验证的最终用户的声明。要获取有关最终​​用户的请求声明,客户端使用通过 OpenID Connect 身份验证获得的访问令牌向 UserInfo 端点发出请求。这些声明通常由 JSON 对象表示,该对象包含声明的名称和值对集合。

与 UserInfo 端点的通信必须使用 TLS。有关使用 TLS 的更多信息, 请参阅第 16.17 节。 (TLS Requirements)

UserInfo 端点必须支持使用RFC 7231 [RFC7231] 中定义的HTTP GET和 HTTP POST方法。 (Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content,” June 2014.)

UserInfo 端点必须接受访问令牌作为 OAuth 2.0 承载令牌用法 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750]。

UserInfo 端点应支持使用 跨源资源共享 (CORS) (Opera Software ASA, “Cross-Origin Resource Sharing,” July 2010.) [CORS] 和/或其他适当的方法,以使 JavaScript 客户端和其他基于浏览器的客户端能够访问它。



目录

5.3.1.用户信息请求

客户端使用 HTTP GET或 HTTP POST 发送 UserInfo 请求。根据OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750] 第 2 节,从 OpenID Connect 身份验证请求获取的访问令牌必须作为承载令牌发送。

建议请求使用 HTTP GET方法,并使用授权标头字段发送访问令牌

以下是 UserInfo 请求的非规范示例:

  GET /userinfo HTTP/1.1
  Host: server.example.com
  Authorization: Bearer SlAV32hkKG


目录

5.3.2.成功的用户信息响应

UserInfo 声明必须作为 JSON 对象的成员返回,除非在客户端注册期间请求签名或加密的响应。可以退回 第 5.1 节 (Standard Claims)中定义的声明,以及此处未指定的其他声明。

出于隐私原因,OpenID 提供商可以选择不返回某些请求的声明的值。不返回所请求的声明并不是错误情况。

如果未返回声明,则应从表示声明的 JSON 对象中省略该声明名称;它不应该与 null 或空字符串值一起出现。

子(主题)声明必须始终在 UserInfo 响应中返回。

注意:由于令牌替换攻击的可能性(请参阅第 16.11 节 (Token Substitution)),用户信息响应不能保证与ID 令牌的(主题)元素标识的最终用户有关。必须验证 UserInfo 响应中的 声明是否与 ID 令牌中的声明完全匹配;如果它们不匹配,则不得使用 UserInfo 响应值。

收到 UserInfo 请求后,UserInfo 端点必须在 HTTP 响应正文中返回 UserInfo 响应的 JSON 序列化,如 第 13.3 节 (JSON Serialization)中所述,除非在注册期间指定了不同的格式 [OpenID.Registration] (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.)。 UserInfo 端点必须返回一个内容类型标头以指示返回哪种格式。如果响应正文是文本 JSON 对象,则HTTP 响应的内容类型必须是application/json ;响应正文应该使用 UTF-8 进行编码。

如果 UserInfo 响应已签名和/或加密,则声明将以 JWT 返回,并且内容类型必须为application/jwt。响应可以在不签名的情况下进行加密。如果同时请求签名和加密,则必须对响应进行签名然后加密,结果是嵌套 JWT,如[JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)中定义。

如果已签名,则 UserInfo 响应必须包含声明 iss(发行者)和aud(受众)作为成员。 iss值必须OP 的颁发者标识符 URL。 aud必须是或包含 RP 的客户端 ID 值。

以下是 UserInfo 响应的非规范示例:

  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"
  }


目录

5.3.3.用户信息错误响应

当发生错误情况时,UserInfo 端点将返回错误响应,如 OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750] 第 3 节中所定义。 (与 RFC 6750 无关的 HTTP 错误将使用适当的 HTTP 状态代码返回给用户代理。)

以下是 UserInfo 错误响应的非规范示例:

  HTTP/1.1 401 Unauthorized
  WWW-Authenticate: Bearer error="invalid_token",
    error_description="The Access Token expired"


目录

5.3.4.用户信息响应验证

客户端必须按如下方式验证 UserInfo 响应:

  1. 根据RFC 6125 (Saint-Andre, P. and J. Hodges, “Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS),” March 2011.) [RFC6125], 通过 TLS 服务器证书检查验证响应的 OP 是否是预期的 OP 。
  2. 如果客户端在注册期间提供了 userinfo_encrypted_response_alg 参数,则使用注册期间指定的密钥解密 UserInfo 响应。
  3. 如果响应已签名,客户端应该根据JWS (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.) [JWS] 验证签名。



目录

5.4.使用范围值请求声明

OpenID Connect 客户端使用OAuth 2.0 [RFC6749]第 3.3 节中定义的范围值来指定为访问令牌请求哪些访问权限。与访问令牌关联的范围决定了哪些资源在用于访问 OAuth 2.0 受保护端点时可用。受保护的资源端点可以根据请求提供的访问令牌时使用的范围值和其他参数执行不同的操作并返回不同的信息。 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.)

对于 OpenID Connect,范围可用于请求将特定信息集作为声明值提供。

以下范围请求的声明被授权服务器视为自愿声明。

OpenID Connect 定义了以下用于请求声明的 范围值:

轮廓
选修的。此范围值请求访问最终用户的默认配置文件声明,其中包括: namefamily_namegiven_namemiddle_namenicknamepreferred_usernameprofilepicturewebsitegenderbirthdatezoneinfolocaleupdated_at
电子邮件
选修的。此范围值请求访问电子邮件email_verified声明。
地址
选修的。该范围值请求访问地址Claim。
电话
选修的。此范围值请求访问phone_numberphone_number_verified声明。

可以通过创建空格分隔、区分大小写的 ASCII 范围值列表来使用多个范围值。

使用导致颁发访问令牌的response_type值时,如第5.3.2节中所述, profileemailaddressphone范围值 请求的声明 将从UserInfo端点返回。但是,当没有颁发访问令牌时( response_typeid_token就是这种情况),生成的声明将在 ID 令牌中返回。 (Successful UserInfo Response)

在某些情况下,最终用户可以选择让 OpenID 提供商拒绝提供 RP 请求的部分或全部信息。为了最大限度地减少最终用户被要求披露的信息量,RP 可以选择仅请求 UserInfo 端点提供的信息的子集。

以下是未编码 范围请求的非规范示例:

  scope=openid profile email phone


目录

5.5.使用“claims”请求参数请求声明

OpenID Connect 定义以下授权请求参数,以允许请求单独的声明并指定适用于所请求的声明的参数:

声明
选修的。该参数用于请求返回特定的声明。该值是一个列出请求的声明的 JSON 对象。

声明身份验证请求参数请求从 UserInfo 端点和/或 ID 令牌中返回特定声明。它表示为一个 JSON 对象,其中包含从这些位置请求的声明列表。所请求的声明的属性也可以被指定。

对声明参数 的支持是可选的。如果 OP 不支持此参数而 RP 使用它,则 OP 应使用其认为合适的任何启发式方法,向 RP 返回一组它认为对 RP 和最终用户有用的声明。 Claims_parameter_supported Discovery 结果指示OP是否支持该参数。

声明 参数值在 OAuth 2.0 请求中表示为 UTF-8 编码的 JSON(当作为 OAuth 参数传递时,最终会进行表单 urlencoded)。当在请求对象值中使用时,根据第 6.1 节 (Passing a Request Object by Value),JSON 用作 声明成员的值。

声明请求 JSON 对象的顶级成员是:

用户信息
选修的。请求从 UserInfo 端点返回列出的各个声明。如果存在,则请求将列出的声明添加到使用范围值请求的任何声明中 。如果不存在,则从 UserInfo 端点请求的声明只是使用 范围值请求的声明。
当使用userinfo成员时,请求还必须使用response_type 值,该值会导致向客户端颁发访问令牌以在 UserInfo 端点处使用。
id_token
选修的。请求在 ID 令牌中返回列出的个人声明。如果存在,则请求将列出的声明添加到 ID 令牌中的默认声明中。如果不存在,则根据第 2 节中的 ID 令牌定义以及第 (ID Token)3.1.3.6 (ID Token)3.2.2.10 (ID Token)3.3.2.11 (ID Token)3.3.3.6 (ID Token) 节中的附加每流 ID 令牌要求 请求默认 ID 令牌声明

其他成员可能会在场。任何不被理解的成员都必须被忽略。

声明请求示例如下:

  {
   "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"] }
    }
  }
请注意,所请求的声明不在第 5.1 节 (Standard Claims) 定义的标准集中 ,(示例) http://example.info/claims/groups声明。使用声明参数是请求无法使用范围值指定的特定声明组合的唯一方法。

目录

5.5.1.个人声明请求

声明请求的 userinfoid_token成员 都是 JSON 对象,其中请求的各个声明的名称作为成员名称。成员值必须是以下之一:

无效的
表示正在以默认方式请求此声明。特别是,这是自愿声明。例如,声明请求:
 "given_name": null
以默认方式 请求给定名称声明。
JSON 对象
用于提供有关所请求的声明的附加信息。该规范定义了以下成员:
基本的
选修的。指示所请求的声明是否为基本声明。如果该值为true,则表明该声明是基本声明。例如,声明请求:
 "auth_time": {"essential": true}  

 
可用于指定必须返回 auth_time声明值。
如果该值为false,则表明它是自愿声明。默认为false
通过请求作为基本声明的声明,RP 向最终用户表明释放这些声明将确保最终用户请求的特定任务的顺利授权。请注意,即使声明因最终用户未授权其发布或声明不存在而不可用,授权服务器在未返回声明时也不得生成错误,无论它们是基本的还是自愿的,除非在具体权利要求的描述。
价值
选修的。请求以特定值返回声明。例如,声明请求:
 "sub": {"value": "248289761001"}  

 
可用于指定请求适用于主题标识符为248289761001 的最终用户。
成员 的值必须是所请求的声明的有效值。各个声明的定义可以包括 在请求该声明时如何以及是否使用限定符的要求。相等比较用于确定请求的 Claim 值是否匹配。
当 Claim 值与请求的值不匹配时,该 Claim 不会包含在响应中。如果声明是sub,则不匹配必须导致身份验证失败,如第 3.1.2.2 节 (Authentication Request Validation)中所述。
价值观
选修的。请求返回带有一组值之一的声明,这些值按优先顺序出现。其处理方式与请求相同,只是提供了可接受的声明值的选择。
例如,声明请求:
  "acr": {"essential": true,
          "values": ["urn:mace:incommon:iap:silver",
                     "urn:mace:incommon:iap:bronze"]}
指定必须 使用值 urn:mace:incommon:iap:silverurn:mace:incommon:iap:bronze返回acr Claim 。
Values成员数组 中的值必须是所请求的声明的有效值。各个声明的定义可以包括 在请求该声明时如何以及是否使用限定符的要求。相等比较用于确定请求的声明值是否匹配。
当 Claim 值与任何请求的值都不匹配时,该 Claim 不会包含在响应中。
可以定义其他成员来提供有关所请求的声明的附加信息。任何不被理解的成员都必须被忽略。

请注意,当支持声明请求参数时,请求声明的范围值(如 第 5.4 节 (Requesting Claims using Scope Values)中定义)是请求单个声明集的有效速记方法。例如,使用范围值openid email 和返回访问令牌的response_type相当于使用范围值openid 和以下针对单个声明的请求。

相当于使用电子邮件范围值:

  {
   "userinfo":
    {
     "email": null,
     "email_verified": null
    }
  }


目录

5.5.1.1.请求“acr”声明

如果acr声明被请求为 ID 令牌的基本声明,并且具有请求特定身份验证上下文类参考的一个或多个值参数,并且实现支持声明参数,则授权服务器必须返回与 所请求的其中之一匹配的acr声明值价值观。授权服务器可以要求最终用户使用其他因素重新进行身份验证以满足此要求。如果这是基本声明并且无法满足要求,则授权服务器必须将该结果视为失败的身份验证尝试。

请注意,RP 可以通过使用acr_values请求参数或在单独的 acr声明请求中不包含 "essential": true 来请求acr 声明作为自愿声明。如果声明不是必需的并且无法提供请求的值,则授权服务器应该返回会话的当前acr作为acr声明的值。如果声明不是必需的,则授权服务器不需要在其响应中提供此声明。

如果客户端同时使用acr_values请求参数和针对列出特定请求值的 ID 令牌的 单独acr Claim 请求来请求acr Claim,则结果行为是未指定的。



目录

5.5.2.个人声明的语言和文字

如第 5.2 节 (Claims Languages and Scripts) 所述,人类可读的声明值和引用人类可读值的声明值可以用多种语言和脚本表示。在对单个声明的请求中,可以通过在声明请求中包含包含#分隔的 BCP47 [RFC5646] 语言标签的声明名称来请求特定声明的请求语言和脚本,使用 (Phillips, A., Ed. and M. Davis, Ed., “Tags for Identifying Languages,” September 2009.)第 5.2 节 (Claims Languages and Scripts)中指定的声明名称语法 。例如,可以使用声明名称family_name#ja-Kana-JP请求日语片假名的姓氏, 并且可以使用声明名称family_name#ja-Hani-JP 请求日语姓氏的汉字表示 。可以使用声明名称website#de来请求德语网站

如果 OP 收到对其不具备的语言和脚本的人类可读声明的请求,则返回的那些不使用所请求的语言和脚本的声明的任何版本都应该在声明名称中使用语言标签。



目录

5.6.声明类型

本规范定义了声明值的三种表示形式:

正常声明
由 OpenID 提供商直接声明的声明。
合计声明
由除 OpenID 提供者之外的声明提供者声明但由 OpenID 提供者返回的声明。
分布式声明
由除 OpenID 提供者之外的声明提供者声明但由 OpenID 提供者作为引用返回的声明。

正常声明必须得到支持。对聚合声明和分布式声明的支持是可选的。



目录

5.6.1.正常声明

普通声明表示为 JSON 对象中的成员。声明名称是成员名称,声明值是成员值。

以下是包含正常声明的非规范响应:

  {
   "sub": "248289761001",
   "name": "Jane Doe",
   "given_name": "Jane",
   "family_name": "Doe",
   "email": "janedoe@example.com",
   "picture": "http://example.com/janedoe/me.jpg"
  }


目录

5.6.2.聚合和分布式声明

聚合和分布式声明通过使用包含声明的 JSON 对象的 特殊_claim_names_claim_sources成员来表示。

_claim_names
JSON 对象,其成员名称是聚合和分布式声明的声明名称。成员值是对_claim_sources成员中的成员名称的引用,可以从中检索实际的声明值。 OP 可以省略声明名称集中引用的声明提供者提供的一些声明。
_claim_来源
JSON 对象,其成员名称由_claim_names成员 的成员值引用 。成员值包含聚合声明集或分布式声明的参考位置。成员值可以具有以下格式之一,具体取决于它是提供聚合声明还是分布式声明:
合计声明
JSON 对象,必须包含JWT成员,其值为JWT (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.) [JWT],必须包含引用相应_claim_sources成员的_claim_names对象中的所有声明。其他成员可能会在场。任何不被理解的成员都必须被忽略。
智威汤逊
必需的。包含声明值的 JWT。
JWT 不应包含(主题)声明,除非其值是声明提供者处的最终用户的标识符(而不是 OpenID 提供者或另一方);这通常意味着不应提供 子声明。
分布式声明
JSON 对象包含以下成员和值:
终点
必需的。可以从中检索关联声明的 OAuth 2.0 资源端点。端点 URL 必须以 JWT 形式返回声明。
访问令牌
选修的。访问令牌允许使用OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750] 协议从端点 URL 检索声明。声明应该使用授权请求头字段来请求,并且声明提供者必须支持此方法。如果访问令牌不可用,RP 可能需要在带外检索访问令牌或使用声明提供者和 RP 之间预先协商的访问令牌,或者声明提供者可以重新验证最终用户和/或重新授权RP。
由于不返回所请求的声明不是错误条件,因此 RP 必须准备好处理 _claim_sources中列出的某些声明未从声明提供者返回的情况。他们应该将其视为与任何其他请求的声明未返回时相同的处理方式。
子(主题)声明不应从声明提供者返回除非其值是声明提供者处最终用户的标识符(而不是 OpenID 提供者或另一方);这通常意味着不应提供 子声明。

iss (颁发者)声明应该包含在声明提供者发布的任何 JWT 中,以便可以检索声明提供者的密钥以进行 JWT 的签名验证声明的值是声明提供者的颁发者标识符 URL。

一般来说,何时适合使用聚合声明和分布式声明由 OP 决定。在某些情况下,有关何时使用哪些声明类型的信息可能会在 RP 和 OP 之间进行带外协商。



目录

5.6.2.1.汇总声明示例

在此非规范示例中,来自声明提供商 A 的声明与 OpenID 提供商持有的其他声明相结合,来自声明提供商 A 的声明作为聚合声明返回。

在此示例中,有关 Jane Doe 的这些声明是由声明提供者 A 发布的。(该示例还包括声明提供者的发布者标识符 URL。)

  {
   "iss": "https://a.example.com",
   "address": {
     "street_address": "1234 Hollywood Blvd.",
     "locality": "Los Angeles",
     "region": "CA",
     "postal_code": "90210",
     "country": "United States of America"},
   "phone_number": "+1 (310) 123-4567"
  }

声明提供者 A 对 JSON 声明进行签名,以签名的 JWT 形式表示它们:jwt_header.jwt_part2.jwt_part3. OpenID 提供商使用的就是这个 JWT。

在此示例中,包含来自声明提供者 A 的 Jane Doe 聚合声明的 JWT 与其他正常声明组合在一起,并作为以下声明集返回:

  {
   "sub": "248289761001",
   "name": "Jane Doe",
   "given_name": "Jane",
   "family_name": "Doe",
   "birthdate": "0000-03-22",
   "eye_color": "blue",
   "email": "janedoe@example.com",
   "_claim_names": {
     "address": "src1",
     "phone_number": "src1"
   },
   "_claim_sources": {
     "src1": {"JWT": "jwt_header.jwt_part2.jwt_part3"}
   }
  }


目录

5.6.2.2.分布式声明示例

在这个非规范示例中,OpenID 提供商将其持有的普通声明与两个不同声明提供商 B 和 C 持有的声明的引用相结合,并将 B 和 C 持有的一些声明的引用合并为分布式声明。

在此示例中,有关 Jane Doe 的这些声明由声明提供者 B(Jane Doe 的银行)持有。 (该示例还包括声明提供者的颁发者标识符 URL。)

  {
   "iss": "https://bank.example.com",
   "shipping_address": {
     "street_address": "1234 Hollywood Blvd.",
     "locality": "Los Angeles",
     "region": "CA",
     "postal_code": "90210",
     "country": "United States of America"},
   "payment_info": "Some_Card 1234 5678 9012 3456",
   "phone_number": "+1 (310) 123-4567"
  }

同样在此示例中,有关 Jane Doe 的此声明由声明提供者 C(信用机构)持有。 (该示例还包括声明提供者的颁发者标识符 URL。)

  {
   "iss": "https://creditagency.example.com",
   "credit_score": 650
  }

OpenID 提供商通过发送可检索分布式声明的位置的访问令牌和 URL,返回 Jane Doe 的声明以及对来自声明提供商 B 和声明提供商 C 的分布式声明的引用:

  {
   "sub": "248289761001",
   "name": "Jane Doe",
   "given_name": "Jane",
   "family_name": "Doe",
   "email": "janedoe@example.com",
   "birthdate": "0000-03-22",
   "eye_color": "blue",
   "_claim_names": {
     "payment_info": "src1",
     "shipping_address": "src1",
     "credit_score": "src2"
    },
   "_claim_sources": {
     "src1": {"endpoint":
                "https://bank.example.com/claim_source"},
     "src2": {"endpoint":
                "https://creditagency.example.com/claims_here",
              "access_token": "ksj3n283dke"}
   }
  }

请注意,不返回由声明提供者 B 持有的 phone_number表明并非需要包括所使用的声明提供者持有的所有声明。



目录

5.7.声称稳定性和独特性

来自 ID 令牌的 sub主题)和 iss(发行者)声明一起使用,是 RP 可以依赖作为最终用户的稳定标识符的唯一声明,因为sub 声明必须是本地唯一的并且永远不会重新分配发行人内针对特定最终用户的信息,如第 2 节 (ID Token)中所述。因此,唯一保证给定最终用户的唯一标识符是iss Claim 和sub Claim 的组合。

所有其他声明在不同发行人之间的长期稳定性或用户之间的唯一性方面不提供此类保证,并且允许发行人应用当地限制和政策。例如,发行人可以 在不同的时间点在不同的最终用户之间 重复使用电子邮件声明值,并且给定最终用户的声明电子邮件地址可能会随着时间的推移而改变。因此,其他声明(例如电子邮件电话号码首选用户名名称) 不得用作最终用户的唯一标识符,无论是从 ID 令牌还是 UserInfo 端点获取。



目录

6. 将请求参数作为 JWT 传递

OpenID Connect 定义以下授权请求参数,以便对身份验证请求进行签名并可选择加密:

要求
可选。此参数允许将 OpenID Connect 请求传递到单个自包含参数中,并可选择进行签名和/或加密。参数值是请求对象值,如第6.1 节 (Passing a Request Object by Value)中所述。它将请求表示为 JWT,其声明是请求参数。
请求地址
选修的。此参数使 OpenID Connect 请求能够通过引用而不是通过值传递。request_uri是引用包含请求对象值的资源的 URL,该值是包含请求参数的 JWT。该 URL 必须使用https方案,除非目标请求对象以 OP 可验证的方式进行签名。

使用这些参数的请求表示为 JWT,分别按值或按引用传递。通过引用传递请求的能力对于大型请求特别有用。如果使用这些参数之一,则不得在同一请求中使用另一个参数。

请注意,此处定义的请求对象与OAuth 2.0 授权框架:JWT 安全授权请求 (JAR) (Sakimura, N., Bradley, J., and M. Jones, “The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR),” August 2021.) [RFC9101] 指定的对象兼容 。



目录

6.1.按值传递请求对象

请求授权请求参数使 OpenID Connect 请求能够在单个独立参数中传递,并且可以选择进行签名和/或加密它将请求表示为 JWT,其声明是第 3.1.2 节 (Authorization Endpoint)中指定的请求参数。该 JWT 称为请求对象。

对请求参数 的支持是可选的。 request_parameter_supported Discovery 结果指示OP是否支持该参数。如果 OP 不支持此参数而 RP 使用它,则 OP 必须返回request_not_supported 错误。

使用请求参数 时,JWT 中包含的 OpenID Connect 请求参数值将取代使用 OAuth 2.0 请求语法传递的参数值。但是,即使使用请求对象,也可以使用 OAuth 2.0 请求语法传递参数;这通常是为了启用包含固定请求参数的缓存的、预签名(并且可能预加密)的请求对象值,而可能随每个请求而变化的参数(例如状态随机数)被传递为OAuth 2.0 参数。

因此,该请求是有效的 OAuth 2.0 授权请求,必须使用 OAuth 2.0 请求语法包含response_typeclient_id参数的值,因为 OAuth 2.0 需要它们。这些参数的值必须与请求对象中的值(如果存在)匹配。

即使请求对象值中存在范围参数,也必须始终使用包含openid范围值的 OAuth 2.0 请求语法来传递 范围参数,以向底层 OAuth 2.0 逻辑表明这是一个 OpenID Connect 请求。

请求对象可以是签名的或未签名的(不安全的)。当它不安全时,这通过 在 JOSE 标头中使用 算法[JWA] (Jones, M., “JSON Web Algorithms (JWA),” May 2015.)来指示。如果签名,请求对象应该包含声明 iss(发行者)和aud(受众)作为成员。 iss值应该是 RP 的客户端 ID,除非它是由与 RP 不同的一方签名的aud应该是或包含 OP 的颁发者标识符 URL。

请求对象也可以使用JWE (Jones, M. and J. Hildebrand, “JSON Web Encryption (JWE),” May 2015.) [JWE] 进行加密,并且可以在不进行签名的情况下进行加密。如果同时执行签名和加密,则必须对其进行签名然后加密,结果是嵌套 JWT,如[JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)中所定义。

requestrequest_uri参数不得包含在请求对象中。

以下是在进行 base64url 编码和签名之前请求对象中的声明的非规范示例:

  {
   "iss": "s6BhdRkqt3",
   "aud": "https://server.example.com",
   "response_type": "code id_token",
   "client_id": "s6BhdRkqt3",
   "redirect_uri": "https://client.example.org/cb",
   "scope": "openid",
   "state": "af0ifjsldkj",
   "nonce": "n-0S6_WzA2Mj",
   "max_age": 86400,
   "claims":
    {
     "userinfo":
      {
       "given_name": {"essential": true},
       "nickname": null,
       "email": {"essential": true},
       "email_verified": {"essential": true},
       "picture": null
      },
     "id_token":
      {
       "gender": null,
       "birthdate": {"essential": true},
       "acr": {"values": ["urn:mace:incommon:iap:silver"]}
      }
    }
  }

使用RS256算法 对其进行签名会产生此请求对象值(值内换行仅用于显示目的):

  eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ew0KICJpc3MiOiAiczZCaGRSa3
  F0MyIsDQogImF1ZCI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsDQogInJl
  c3BvbnNlX3R5cGUIOiAiY29kZSBpZF90b2tlbiIsDQogImNsaWVudF9pZCI6ICJzNk
  JoZFJrcXQzIiwNCiAicmVkaXJlY3RfdXJpIjogImh0dHBzOi8vY2xpZW50LmV4YW1w
  bGUub3JnL2NiIiwNCiAic2NvcGUIOiAib3BlbmlkIiwNCiAic3RhdGUIOiAiYWYwaW
  Zqc2xka2oiLA0KICJub25jZSI6ICJuLTBTNl9XekEyTWoiLA0KICJtYXhfYWdlIjog
  ODY0MDAsDQogImNSYWltcyI6IA0KICB7DQogICAidXNlcmluZm8iOiANCiAgICB7DQ
  ogICAgICJnaXZlbl9uYW1lIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiagICAgIm5p
  Y2tuYW1lIjogbnVsbCwNCiAgICAgImVtYWlsIjogeyJlc3NlbnRpYWwiOiB0cnVlfS
  WNCiAgICAgImVtYWlsX3ZlcmlmaWVkIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiAg
  ICAgInBpY3R1cmUiOiBudWxsDQogICAgfSwNCiagICJpZF90b2tlbiI6IA0KICAgIH
  SNCIAGICAgImdlbmRlciI6IG51bGwsDQogICAgICJiaXJ0aGRhdGUIOiB7ImVzc2Vu
  dGlhbCI6IHRydWV9LA0KICAgICAiYWNyIjogeyJ2YWx1ZXMiOiBbInVybjptYWNlOM
  LUY29tbW9uOmlhcDpzaWx2ZXIiXX0NCiAgICB9DQogIH0NCn0.nwwnNsk1-Zkbmnvs
  F6zTHm8CHERFMGQPhos-EJcaH4Hh-sMgk8ePrGhw_trPYs8KQxsn6R9Emo_wHwajyF
  KzuMXZFSZ3p6Mb8dkxtVyjoy2GIzvuJT_u7PkY2t8QU9hjBchs68PkgjDVTrG1uRTx
  0GxFbuPbj96tVuj11pTnmFCUR6IEOXKYr7iGOCRB3btfJhM0_AKQUfqKnRlrRscc8K
  ol-cSLWoYE9l5QqholImzjT_cmMnNIznW9E7CDyWXTsO70xnB4SkG6pXfLSjLLlxmpG
  iyon_-Te111V8uE83IlzCYIb_NMXvtTIVc1jpspnTSD7xMbpL-2QgwUsAlMGzw

以下以 JWK 格式表示的 RSA 公钥可用于验证此请求对象示例和后续请求对象示例中的请求对象签名(值内换行仅用于显示目的):

  {
   "kty":"RSA",
   "kid":"k2bdc",
   "n":"y9Lqv4fCp6Ei-u2-ZCKq83YvbFEk6JMs_pSj76eMkddWRuWX2aBKGHAtKlE5P
        7_vn__PCKZWePt3vGkB6ePgzAFu08NmKemwE5bQI0e6kIChtt_6KzT5OaaXDF
        I6qCLJmk51Cc4VYFaxgqevMncYrzaW_50mZ1yGSFIQzLYP8bijAHGVjdEFgZa
        ZEN9lsn_GdWLaJpHrB3ROlS50E45wxrlg9xMncVb8qDPuXZarvghLL0HzOuYR
        adBJVoWZowDNTpKpk2RklZ7QaBO7XDv3uR7s_sf2g-bAjSYxYUGsqkNA9b3xV
        W53am_UZZ3tZbFTIh557JICWKHlWj5uzeJXaw",
   "e":"AQAB"
  }


目录

6.1.1.使用“request”请求参数进行请求

客户端向授权端点发送授权请求。

以下是使用请求参数的授权请求的非规范示例 值内换行仅用于显示目的):

  https://server.example.com/authorize?
    response_type=code%20id_token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj
    &request=eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ew0KICJpc3MiOiA
    iczZCaGRSa3F0MyIsDQogImF1ZCI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmN
    vbSIsDQogInJlc3BvbnNlX3R5cGUiOiAiY29kZSBpZF90b2tlbiIsDQogImNsaWV
    udF9pZCI6ICJzNkJoZFJrcXQzIiwNCiAicmVkaXJlY3RfdXJpIjogImh0dHBzOi8
    vY2xpZW50LmV4YW1wbGUub3JnL2NiIiwNCiAic2NvcGUiOiAib3BlbmlkIiwNCiA
    ic3RhdGUiOiAiYWYwaWZqc2xka2oiLA0KICJub25jZSI6ICJuLTBTNl9XekEyTWo
    iLA0KICJtYXhfYWdlIjogODY0MDAsDQogImNsYWltcyI6IA0KICB7DQogICAidXN
    lcmluZm8iOiANCiAgICB7DQogICAgICJnaXZlbl9uYW1lIjogeyJlc3NlbnRpYWw
    iOiB0cnVlfSwNCiAgICAgIm5pY2tuYW1lIjogbnVsbCwNCiAgICAgImVtYWlsIjo
    geyJlc3NlbnRpYWwiOiB0cnVlfSwNCiAgICAgImVtYWlsX3ZlcmlmaWVkIjogeyJ
    lc3NlbnRpYWwiOiB0cnVlfSwNCiAgICAgInBpY3R1cmUiOiBudWxsDQogICAgfSw
    NCiAgICJpZF90b2tlbiI6IA0KICAgIHsNCiAgICAgImdlbmRlciI6IG51bGwsDQo
    gICAgICJiaXJ0aGRhdGUiOiB7ImVzc2VudGlhbCI6IHRydWV9LA0KICAgICAiYWN
    yIjogeyJ2YWx1ZXMiOiBbInVybjptYWNlOmluY29tbW9uOmlhcDpzaWx2ZXIiXX0
    NCiAgICB9DQogIH0NCn0.nwwnNsk1-ZkbmnvsF6zTHm8CHERFMGQPhos-EJcaH4H
    h-sMgk8ePrGhw_trPYs8KQxsn6R9Emo_wHwajyFKzuMXZFSZ3p6Mb8dkxtVyjoy2
    GIzvuJT_u7PkY2t8QU9hjBcHs68PkgjDVTrG1uRTx0GxFbuPbj96tVuj11pTnmFC
    UR6IEOXKYr7iGOCRB3btfJhM0_AKQUfqKnRlrRscc8Kol-cSLWoYE9l5QqholImz
    jT_cMnNIznW9E7CDyWXTsO70xnB4SkG6pXfLSjLLlxmPGiyon_-Te111V8uE83Il
    zCYIb_NMXvtTIVc1jpspnTSD7xMbpL-2QgwUsAlMGzw


目录

6.2.通过引用传递请求对象

request_uri授权请求 参数允许 OpenID Connect 请求通过引用而不是通过值传递。此参数的使用方式与 请求参数相同,不同之处在于请求对象值是从指定 URL 的资源中检索的,而不是按值传递的。

request_uri_parameter_supported Discovery 结果指示OP是否支持该参数。如果 OP 不支持此参数而 RP 使用它,则 OP 必须返回request_uri_not_supported 错误。

使用request_uri参数 时,引用的 JWT 中包含的 OpenID Connect 请求参数值将取代使用 OAuth 2.0 请求语法传递的参数值。但是,即使使用request_uri,参数也可以使用 OAuth 2.0 请求语法传递;这通常是为了启用包含固定请求参数的缓存的、预签名(并且可能预加密)的请求对象值,而可能随每个请求而变化的参数(例如状态随机数)被传递为OAuth 2.0 参数。

因此,该请求是有效的 OAuth 2.0 授权请求,必须使用 OAuth 2.0 请求语法包含response_typeclient_id参数的值,因为 OAuth 2.0 需要它们。这些参数的值必须与请求对象中的值(如果存在)匹配。

即使引用的请求对象中存在范围参数,也必须始终使用包含openid范围值的 OAuth 2.0 请求语法来传递 范围参数,以向底层 OAuth 2.0 逻辑指示这是一个 OpenID Connect 请求。

服务器可以缓存请求 URI 引用的资源的内容。如果引用资源的内容可能会更改,则 URI 应包含引用资源内容的 base64url 编码的 SHA-256 哈希值作为 URI 的片段组件。如果用于 URI 的片段值发生更改,则会向服务器发出信号,表明该 URI 的任何具有旧片段值的缓存值都不再有效。

请注意,客户端可以使用OpenID Connect 动态客户端注册 1.0 [OpenID.Registration] 规范第 2.1 节中定义的 request_uris参数来 预先注册 request_uri值 。 OP 可以要求使用require_request_uri_registration发现参数预先注册所使用的request_uri值 。 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.)

整个请求 URI 不应超过 512 个 ASCII 字符。

URL 引用的资源内容必须是请求对象。request_uri值中使用的方案 必须是https,除非目标请求对象以授权服务器可验证的方式进行签名。 request_uri值必须可以被授权服务器访问,并且应该可以被客户端访问

以下是可由request_uri引用的请求对象资源内容的非规范示例 (值内换行仅用于显示目的):

  eyJhbGciOiJSUzI1NiIsImtpZCI6ImsyYmRjIn0.ew0KICJpc3MiOiAiczZCaGRSa3
  F0MyIsDQogImF1ZCI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsDQogInJl
  c3BvbnNlX3R5cGUIOiAiY29kZSBpZF90b2tlbiIsDQogImNsaWVudF9pZCI6ICJzNk
  JoZFJrcXQzIiwNCiAicmVkaXJlY3RfdXJpIjogImh0dHBzOi8vY2xpZW50LmV4YW1w
  bGUub3JnL2NiIiwNCiAic2NvcGUIOiAib3BlbmlkIiwNCiAic3RhdGUIOiAiYWYwaW
  Zqc2xka2oiLA0KICJub25jZSI6ICJuLTBTNl9XekEyTWoiLA0KICJtYXhfYWdlIjog
  ODY0MDAsDQogImNSYWltcyI6IA0KICB7DQogICAidXNlcmluZm8iOiANCiAgICB7DQ
  ogICAgICJnaXZlbl9uYW1lIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiagICAgIm5p
  Y2tuYW1lIjogbnVsbCwNCiAgICAgImVtYWlsIjogeyJlc3NlbnRpYWwiOiB0cnVlfS
  WNCiAgICAgImVtYWlsX3ZlcmlmaWVkIjogeyJlc3NlbnRpYWwiOiB0cnVlfSwNCiAg
  ICAgInBpY3R1cmUiOiBudWxsDQogICAgfSwNCiagICJpZF90b2tlbiI6IA0KICAgIH
  SNCIAGICAgImdlbmRlciI6IG51bGwsDQogICAgICJiaXJ0aGRhdGUIOiB7ImVzc2Vu
  dGlhbCI6IHRydWV9LA0KICAgICAiYWNyIjogeyJ2YWx1ZXMiOiBbInVybjptYWNlOM
  LUY29tbW9uOmlhcDpzaWx2ZXIiXX0NCiAgICB9DQogIH0NCn0.nwwnNsk1-Zkbmnvs
  F6zTHm8CHERFMGQPhos-EJcaH4Hh-sMgk8ePrGhw_trPYs8KQxsn6R9Emo_wHwajyF
  KzuMXZFSZ3p6Mb8dkxtVyjoy2GIzvuJT_u7PkY2t8QU9hjBchs68PkgjDVTrG1uRTx
  0GxFbuPbj96tVuj11pTnmFCUR6IEOXKYr7iGOCRB3btfJhM0_AKQUfqKnRlrRscc8K
  ol-cSLWoYE9l5QqholImzjT_cmMnNIznW9E7CDyWXTsO70xnB4SkG6pXfLSjLLlxmpG
  iyon_-Te111V8uE83IlzCYIb_NMXvtTIVc1jpspnTSD7xMbpL-2QgwUsAlMGzw


目录

6.2.1.引用请求对象的 URI

客户端将请求对象资源存储在本地或远程到服务器可以访问的 URL 处。此 URL 是请求 URI request_uri

如果请求对象包含声明请求的值,则不得将其透露给授权服务器以外的任何人。因此,request_uri在其生命周期内必须具有适当的熵。如果知道不会再次使用或在合理的超时后除非采取访问控制措施,建议将其删除。

以下是请求 URI 值的非规范示例(值内换行仅用于显示目的):

  https://client.example.org/request.jwt#
    GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM


目录

6.2.2.使用“request_uri”请求参数进行请求

客户端向授权端点发送授权请求。

以下是使用request_uri参数的授权请求的非规范示例(值内换行仅用于显示目的):

  https://server.example.com/authorize?
    response_type=code%20id_token
    &client_id=s6BhdRkqt3
    &request_uri=https%3A%2F%2Fclient.example.org%2Frequest.jwt
    %23GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM
    &state=af0ifjsldkj&nonce=n-0S6_WzA2Mj
    &scope=openid


目录

6.2.3.授权服务器获取请求对象

收到请求后,授权服务器必须request_uri发送 HTTP GET请求 以检索引用的请求对象(除非它已被缓存),并解析它以重新创建授权请求参数。

请注意,RP 应使用不同参数为每个请求使用唯一的 URI,否则会阻止授权服务器缓存request_uri

以下是此获取过程的非规范示例:

  GET /request.jwt HTTP/1.1
  Host: client.example.org


目录

6.2.4. “request_uri”基本原理

选择使用 request_uri参数的原因有多种:

  1. 请求参数集可能会变得很大,并可能超出浏览器 URI 大小限制。通过引用传递请求参数可以解决此问题。
  2. 传递request_uri值,而不是按值传递完整请求,可以减少请求延迟。
  3. 大多数来自 RP 的声明请求都是恒定的。 request_uri是一种提前创建一组常量请求参数(有时还对其进行签名和加密)的方法request_uri值成为代表一组特定固定请求参数的“工件”。)
  4. 在注册时预先注册一组固定的请求参数使 OP 能够在注册时缓存并预先验证请求参数,这意味着不需要在请求时检索它们。
  5. 在注册时预先注册一组固定的请求参数,使 OP 能够自行或通过第三方从消费者保护和其他角度审查请求的内容。



目录

6.3.验证基于 JWT 的请求

使用requestrequest_uri授权请求参数时,除了第 3.1.2.2 (Authentication Request Validation)3.2.2.2 (Authentication Request Validation)3.3.2.2 (Authentication Request Validation)节中指定的步骤之外,还必须执行其他步骤来验证身份验证请求。这些步骤是验证包含请求对象的 JWT 并验证请求对象本身。



目录

6.3.1.加密请求对象

如果授权服务器在其发现文档[OpenID.Discovery]的request_object_encryption_alg_values_supportedrequest_object_encryption_enc_values_supported元素中公布了 JWE 加密算法,或者通过其他方式提供了加密算法,则客户端将使用这些算法来加密 JWT。 (Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” December 2023.)

授权服务器必须根据JSON Web 加密 (Jones, M. and J. Hildebrand, “JSON Web Encryption (JWE),” May 2015.)[JWE] 规范对 JWT 进行解密。结果可以是签名或未签名(不安全)的请求对象。在前一种情况下,必须按照第 6.3.2 节 (Signed Request Object)中的定义执行签名验证

如果解密失败,授权服务器必须返回错误。



目录

6.3.2.签名请求对象

要执行签名验证, JOSE 标头中的alg标头参数必须与客户端注册[OpenID.Registration]期间设置的request_object_signing_alg的值或通过其他方式预先注册的值匹配。必须根据该client_id 和算法 的适当密钥来验证签名。 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.)

如果签名验证失败,授权服务器必须返回错误。



目录

6.3.3.请求参数组装和验证

授权服务器必须从请求对象值和 OAuth 2.0 授权请求参数(减去requestrequest_uri参数) 中组装要使用的授权请求参数集。如果请求对象和OAuth授权请求参数中存在相同的参数,则使用请求对象中的参数。使用授权请求参数的组装集,授权服务器然后以正在使用的流的正常方式验证请求,如第3.1.2.2 (Authentication Request Validation)3.2.2.2 (Authentication Request Validation)3.3.2.2 (Authentication Request Validation)节中指定的。



目录

7. 自发行OpenID提供商

OpenID Connect 支持自发行 OpenID 提供商 - 发行自签名 ID 令牌的个人、自托管 OP。自发行 OP 使用特殊的发行者标识符 https://self-issued.me

用于与自发布 OP 通信的消息大部分与用于与其他 OP 通信的消息相同。本节定义了所使用的少数附加参数以及自发行情况下某些参数值的规范。



目录

7.1.自发行 OpenID 提供商发现

如果发现过程的输入标识符包含域 self-issued.me,则不执行动态发现。相反,使用以下静态配置值:

  {
   "authorization_endpoint":
     "openid:",
   "issuer":
     "https://self-issued.me",
   "scopes_supported":
     ["openid", "profile", "email", "address", "phone"],
   "response_types_supported":
     ["id_token"],
   "subject_types_supported":
     ["pairwise"],
   "id_token_signing_alg_values_supported":
     ["RS256"],
   "request_object_signing_alg_values_supported":
     ["none", "RS256"]
  }

注意:OpenID 基金会计划托管 OpenID Provider 站点 https://self-issued.me/,包括其 WebFinger 服务,以便对其执行发现返回上述静态发现信息,使 RP 不需要任何特殊处理发现自行发行的 OP。该网站将在实验的基础上进行托管。如果 OpenID 基金会随后承诺以用于生产用途的方式托管该站点,则生产实施不应依赖它。



目录

7.2.自发行 OpenID 提供商注册

使用自行发行的 OP 时,无需注册。客户端无需注册即可继续操作,就像已在 OP 中注册并获得以下客户端注册响应一样:

客户ID
客户端的 redirect_uri值。
客户端秘密过期时间
0

注意:OpenID 基金会计划托管(无状态)端点 https://self-issued.me/registration/1.0/ ,该端点返回上述响应,使 RP 不需要任何特殊处理即可向自行发布的 OP 进行注册。该网站将在实验的基础上进行托管。如果 OpenID 基金会随后承诺以用于生产用途的方式托管该站点,则生产实施不应依赖它。



目录

7.2.1.使用“注册”请求参数提供信息

OpenID Connect 定义了以下授权请求参数,以使客户端能够向自行颁发的 OpenID 提供商提供附加注册信息:

登记
选修的。客户端使用此参数向自行发布的 OP 提供有关其自身的信息,这些信息通常在动态客户端注册期间提供给 OP。该值是一个包含客户端元数据值的 JSON 对象,如 OpenID Connect 动态客户端注册 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.) [OpenID.Registration] 规范的第 2.1 节中所定义。当 OP 不是自行发布的 OP 时,不应使用 注册参数。

自发布的 OP 不需要这些信息,因此该参数的使用是可选的。

注册 参数值在 OAuth 2.0 请求中表示为 UTF-8 编码的 JSON 对象(当作为 OAuth 参数传递时,最终会进行表单 urlencoded)。当在请求对象值中使用时,根据第 6.1 节 (Passing a Request Object by Value),JSON 对象用作 注册成员的值。

通常在对自行发出的 OP 的请求中使用的注册参数是 policy_uritos_urilogo_uri。如果客户端使用多个重定向URI, 则将使用redirect_uris 参数来注册它们。最后,如果客户端请求加密响应,它通常会使用 jwks_uriid_token_encrypted_response_algid_token_encrypted_response_enc参数。



目录

7.3.自行发出的 OpenID 提供商请求

自发行OP的授权端点是URI openid:

客户端将身份验证请求发送到授权端点,其中包含以下参数:

范围
必需的。 范围参数值,如第 3.1.2 节 (Authorization Endpoint)中指定。
响应类型
必需的。常量字符串值id_token
客户ID
必需的。客户端的客户端ID值,在本例中包含 客户端的redirect_uri值。由于客户端的 redirect_uri URI 值作为客户端ID 进行通信,因此redirect_uri参数不需要也包含在请求中。
id_token_hint
选修的。 id_token_hint参数值,如第 3.1.2 节 (Authorization Endpoint)中指定。不支持将内容加密到自行发布的 OP。
声明
选修的。 声明参数值,如第 5.5 节 (Requesting Claims using the "claims" Request Parameter)中指定。
登记
选修的。客户端使用此参数向自行发布的 OP 提供有关其自身的信息,这些信息通常在动态客户端注册期间提供给 OP,如第7.2.1 节 (Providing Information with the "registration" Request Parameter)中所指定。
要求
选修的。请求对象值,如第 6.1 节 (Passing a Request Object by Value)中指定。不支持将内容加密到自行发布的 OP。

可以发送其他参数。请注意,所有声明都在 ID 令牌中返回。

整个 URL 不得超过 2048 个 ASCII 字符。

以下是客户端的非规范示例 HTTP 302 重定向响应,它触发用户代理向自行发出的 OpenID 提供商发出身份验证请求(值内换行仅用于显示目的):

  HTTP/1.1 302 Found
  Location: openid://?
    response_type=id_token
    &client_id=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile
    &state=af0ifjsldkj
    &nonce=n-0S6_WzA2Mj
    &registration=%7B%22logo_uri%22%3A%22https%3A%2F%2F
      client.example.org%2Flogo.png%22%7D


目录

7.4.自发布 OpenID 提供商响应

OpenID Connect 定义了以下声明以在自行发布的 OpenID 提供商响应中使用:

子_jwk
必需的。用于检查自行颁发的 OpenID 提供商颁发的 ID 令牌签名的公钥,如第 7 节 (Self-Issued OpenID Provider)中所指定。该密钥是 JWK [JWK] (Jones, M., “JSON Web Key (JWK),” May 2015.)格式的裸密钥(不是 X.509 证书值)。sub_jwk是一个 JSON 对象。当 OP 不是自行颁发时,不建议 使用sub_jwk声明。

自发布 OpenID 提供商响应与正常隐式流响应相同,但有以下改进。由于它是隐式流响应,因此响应参数将在 URL 片段组件中返回,除非指定了不同的响应模式。

  1. iss (发行人)声明价值 https://self-issued.me
  2. 存在sub_jwk Claim,其值是用于检查 ID Token 签名的公钥。
  3. sub (主题)Claim 值是sub_jwk Claim密钥的指纹的 base64url 编码表示形式。此指纹值计算为 JWK 的 UTF-8 表示形式的八位字节的 SHA-256 哈希,该 JWK 构造仅包含表示密钥的必需成员,成员名称按字典顺序排序,并且没有空格或换行符。例如,当kty值为 RSA时,成员名称 ektyn 是在指纹计算中使用的构造的 JWK 中存在的成员名称,并按该顺序出现;当kty值为 EC时,成员名称 crvktyxy 按该顺序出现。请注意,此指纹计算与 JWK Thumbprint [JWK.Thumbprint]规范中定义的计算相同 (Jones, M. and N. Sakimura, “JSON Web Key (JWK) Thumbprint,” September 2015.)
  4. 访问 UserInfo 端点时不会返回访问令牌,因此返回的所有声明必须位于 ID 令牌中。



目录

7.5.自发行 ID 令牌验证

要验证收到的 ID 令牌,客户端必须执行以下操作:

  1. 客户必须验证iss(发行者)声明 的值是https://self-issued.me。如果iss包含不同的值,则 ID 令牌不是自行颁发的,而是必须根据 第 3.1.3.7 节 (ID Token Validation)进行验证。
  2. 客户端必须验证 aud (受众)声明是否包含 客户端在身份验证请求中作为受众发送的 redirect_uri值。
  3. 客户端必须根据 JWS [JWS],使用 JOSE 标头的 (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.)alg标头参数中指定的算法 ,使用sub_jwk声明中的密钥来验证 ID 令牌的签名;该密钥是 JWK 格式的裸密钥(不是 X.509 证书值)。
  4. alg值应该RS256的默认值 。它也可能是ES256
  5. 客户端必须验证sub Claim 值是sub_jwk Claim中密钥指纹的 base64url 编码表示形式,如第 7.4 节 (Self-Issued OpenID Provider Response)中所指定。
  6. 当前时间必须早于exp声明 所表示的时间 (可能允许一些小的余地来解决时钟偏差)。
  7. iat Claim 可用于拒绝距当前时间太远的令牌,从而限制为防止攻击而需要存储的随机数的时间可接受的范围是客户特定的。
  8. 必须存在随机数 声明,并检查其值以验证它是否与身份验证请求中发送的值相同。客户端应该检查重放攻击的随机数值。检测重放攻击的精确方法是客户端特定的。

以下是经过 base64url 解码的自发行 ID 令牌的非规范示例(值内换行仅用于显示目的):

  {
   "iss": "https://self-issued.me",
   "sub": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs",
   "aud": "https://client.example.org/cb",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "sub_jwk": {
     "kty":"RSA",
     "n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx
     4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMs
     tn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2
     QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbI
     SD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqb
     w0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
     "e":"AQAB"
    }
  }


目录

8. 主题标识符类型

主体标识符是最终用户在发行者中本地唯一且永不重新分配的标识符,旨在由客户端使用。本规范定义了两种主题标识符类型:

民众
为所有客户提供了相同的(主题)价值。如果提供者 在其发现文档中 没有subject_types_supported元素,则这是默认值。
成对的
这为每个客户提供了不同的 值,以免客户在未经许可的情况下关联最终用户的活动。

OpenID 提供者的发现文档必须在 subject_types_supported元素中列出其支持的主题标识符类型。如果数组中列出了不止一种类型,客户端可以选择 在注册期间 使用subject_type参数提供其首选标识符类型。



目录

8.1.成对标识符算法

当使用成对主题标识符时,OpenID 提供商必须 为每个扇区标识符计算唯一的(主题)值。主体标识符值不得被 OpenID 提供商以外的任何一方逆转。

使用成对值并支持 动态客户端注册 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.)[OpenID.Registration]的提供者应该使用sector_identifier_uri参数。它为共同管理控制下的一组网站提供了一种方法,使其具有 独立于各个域名的一致的成对值。它还为客户端提供了一种更改 redirect_uri域的方法,而无需重新注册所有用户。

如果客户端没有 在动态客户端注册[OpenID.Registration]中 为sector_identifier_uri提供值,则用于成对标识符计算的扇区标识符是注册的redirect_uri的主机组件。如果注册的redirect_uris中有多个主机名 ,客户端必须注册一个 sector_identifier_uri (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.)

当提供sector_identifier_uri时 ,该URL的主机部分将用作成对标识符计算的扇区标识符。ector_identifier_uri的值必须是使用https方案的 URL ,该 URL 指向包含redirect_uri值数组的 JSON 文件 。注册的redirect_uris的值 必须包含在数组的元素中。

OpenID 提供商可以使用具有以下属性的任何算法来计算成对主题标识符:

三个示例方法是:

  1. 扇区标识符可以与本地帐户 ID 和提供商保密的盐值连接起来。然后使用适当的算法对连接的字符串进行哈希处理。

    计算sub = SHA-256 (sector_identifier || local_account_id || salt)。

  2. 扇区标识符可以与本地帐户 ID 和提供商保密的盐值连接起来。然后使用适当的算法对连接的字符串进行加密。

    计算sub = AES-128 (sector_identifier || local_account_id || salt)。

  3. 发行者为扇区标识符和本地帐户 ID 对创建全局唯一标识符 (GUID) 并存储该值。



目录

9. 客户端认证

本节定义了一组客户端身份验证方法,客户端使用这些方法在使用令牌端点时向授权服务器进行身份验证。在客户端注册期间,RP(客户端)可以注册客户端身份验证方法。如果没有注册方法,则默认方法是client_secret_basic

这些客户端身份验证方法是:

客户端秘密基本
从授权服务器收到client_secret值的客户端根据OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 的第 2.3.1 节,使用 HTTP 基本身份验证方案向授权服务器进行身份验证。
客户端秘密帖子
从授权服务器收到client_secret值的客户端,根据OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 2.3.1 节,通过在请求正文中包含客户端凭证来向授权服务器进行身份验证。
客户端秘密jwt
从授权服务器收到client_secret值的客户端使用 HMAC SHA 算法(例如 HMAC SHA-256)创建 JWT。 HMAC(基于哈希的消息身份验证代码)是使用client_secret的 UTF-8 表示形式的八位字节作为共享密钥来计算的。
客户端根据 OAuth 2.0 客户端身份验证和授权授予的 JSON Web 令牌 (JWT) 配置文件 (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)[OAuth.JWT] 以及 OAuth 2.0 客户端身份验证和授权授予的断言框架 (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)[OAuth.Assertions] 进行身份验证。 JWT 必须包含以下必需的声明值,并且可以包含以下可选的声明值:
国际空间站
必需的。发行人。这必须包含OAuth 客户端的 client_id 。
必需的。主题。这必须包含OAuth 客户端的 client_id 。
音频
必需的。观众。 aud 观众)声明。将授权服务器标识为目标受众的值。授权服务器必须验证它是否是令牌的预期受众。受众应该是授权服务器令牌端点的 URL。
吉蒂
必需的。智威汤逊 ID。令牌的唯一标识符,可用于防止令牌重复使用。这些代币只能使用一次,除非双方协商了重复使用的条件;任何此类协商均超出了本规范的范围。
经验值
必需的。到期时间或之后不得接受 JWT 进行处理。
我在
选修的。 JWT 的发布时间。
JWT 可能包含其他声明。任何不被理解的声明都必须被忽略。
身份验证令牌必须作为[OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.) client_assertion参数的值发送
根据[OAuth.JWT],[OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.) client_assertion_type参数的值 必须为“urn:ietf:params:oauth:client-assertion-type:jwt-bearer” (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)
私钥_jwt
已注册公钥的客户端使用该密钥签署 JWT。客户端根据 OAuth 2.0 客户端身份验证和授权授予的 JSON Web 令牌 (JWT) 配置文件 (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)[OAuth.JWT] 以及 OAuth 2.0 客户端身份验证和授权授予的断言框架 (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)[OAuth.Assertions] 进行身份验证。 JWT 必须包含以下必需的声明值,并且可以包含以下可选的声明值:
国际空间站
必需的。发行人。这必须包含OAuth 客户端的 client_id 。
必需的。主题。这必须包含OAuth 客户端的 client_id 。
音频
必需的。观众。 aud 观众)声明。将授权服务器标识为目标受众的值。授权服务器必须验证它是否是令牌的预期受众。受众应该是授权服务器令牌端点的 URL。
吉蒂
必需的。智威汤逊 ID。令牌的唯一标识符,可用于防止令牌重复使用。这些代币只能使用一次,除非双方协商了重复使用的条件;任何此类协商均超出了本规范的范围。
经验值
必需的。到期时间或之后不得接受 JWT 进行处理。
我在
选修的。 JWT 的发布时间。
JWT 可能包含其他声明。任何不被理解的声明都必须被忽略。
身份验证令牌必须作为[OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.) client_assertion参数的值发送
根据[OAuth.JWT],[OAuth.Assertions] (Campbell, B., Mortimore, C., Jones, M., and Y. Goland, “Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.) client_assertion_type参数的值 必须为“urn:ietf:params:oauth:client-assertion-type:jwt-bearer” (Jones, M., Campbell, B., and C. Mortimore, “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants,” May 2015.)

例如(值内换行仅用于显示目的):

  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded

  grant_type=authorization_code&
    code=i1WsRn1uB1&
    client_id=s6BhdRkqt3&
    client_assertion_type=
    urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
    client_assertion=PHNhbWxwOl ... ZT
没有任何
客户端不在令牌端点处对自身进行身份验证,因为它仅使用隐式流(因此不使用令牌端点),或者因为它是没有客户端密钥或其他身份验证机制的公共客户端。



目录

10. 签名和加密

根据发送消息所采用的传输方式,可能无法保证消息的完整性,并且可能无法验证消息的发起者。为了减轻这些风险,ID 令牌、UserInfo 响应、请求对象和客户端身份验证 JWT 值可以利用 JSON Web 签名 (JWS) (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.) [JWS] 对其内容进行签名。为了实现消息机密性,这些值还可以使用 JSON Web Encryption (JWE) (Jones, M. and J. Hildebrand, “JSON Web Encryption (JWE),” May 2015.) [JWE] 来加密其内容。

当消息同时经过签名和加密时,必须根据第 16.14 节 (Signing and Encryption Order)先对其进行签名,然后进行加密,结果是嵌套 JWT,如[JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)中指定的。请注意,所有 JWE 加密方法都会执行完整性检查。

OP 在其 Discovery 文档中宣传其支持的签名和加密算法,或者可以通过其他方式提供此信息。 RP 在其动态注册请求中声明其所需的签名和加密算法,或者可以通过其他方式传达此信息。

OP 通过其 Discovery 文档公布其公钥,或者可以通过其他方式提供此信息。 RP 通过其动态注册请求声明其公钥,或者可以通过其他方式传达此信息。



目录

10.1.签约

签名方必须根据接收方支持的算法选择签名算法。

不对称签名
当使用 RSA 或 ECDSA 签名时, JOSE 标头的alg标头参数值必须设置为JSON Web 算法 (Jones, M., “JSON Web Algorithms (JWA),” May 2015.)[JWA] 中定义的适当算法。用于对内容进行签名的私钥必须与发送者在其 JWK Set 文档中发布的用于签名验证的公钥相关联。如果引用的 JWK Set 文档中有多个键,则 必须在 JOSE 标头中提供kid值。各个密钥的密钥用法必须支持签名。
对称签名
当使用基于 MAC 的签名时, JOSE 标头的alg标头参数值必须设置为 MAC 算法,如JSON Web 算法 (Jones, M., “JSON Web Algorithms (JWA),” May 2015.)[JWA] 中定义。使用的 MAC 密钥是client_secret值的 UTF-8 表示形式的八位字节。有关client_secret值的熵要求的讨论,请参见第 16.19 节 (Symmetric Key Entropy)。公共(非机密)客户端不得使用对称签名,因为它们无法保守秘密。

有关签名请求需求的安全注意事项, 请参阅第 16.20 节。 (Need for Signed Requests)



目录

10.1.1.非对称签名密钥的轮换

签名密钥的轮换可以通过以下方法完成。签名者在其jwks_uri位置的 JWK 集中发布其密钥,并将签名密钥的孩子包含在每条消息的 JOSE 标头中,以向验证者指示哪个密钥将用于验证签名。可以通过定期将新密钥添加到jwks_uri位置的 JWK 集来滚动更新密钥。签名者可以自行决定开始使用新密钥,并使用孩子值向验证者发出更改信号。当验证者看到不熟悉的孩子值时,知道要返回jwks_uri位置重新检索密钥 jwks_uri中的 JWK Set 文档 应该将最近停用的签名密钥保留一段合理的时间,以促进平稳过渡。



目录

10.2.加密

加密方必须根据接收方支持的算法选择加密算法。

非对称加密:RSA
内容加密的公钥必须是接收者在其 JWK Set 文档中发布的用于加密的公钥。如果引用的 JWK Set 文档中有多个键,则 必须在 JOSE 标头中提供kid值。使用支持的 RSA 加密算法来加密随机内容加密密钥,以用于加密签名的 JWT。各个密钥的密钥使用必须包括加密。
非对称加密:椭圆曲线
为JOSE 标头的epk元素 创建临时椭圆曲线公钥。用于密钥协商计算的另一个公钥必须是接收者在其 JWK Set 文档中发布的公钥。如果引用的 JWK Set 文档中有多个键,则 必须在 JOSE 标头中提供kid值。使用 ECDH-ES 算法就用于加密签名 JWT 的内容加密密钥达成一致。各个密钥的密钥使用必须支持加密。
对称加密
对称加密密钥是 通过使用client_secret的 UTF-8 表示形式的八位字节的截断 SHA-2 散列的最左边位从client_secret值派生的。对于 256 位或更少位的密钥,使用 SHA-256;对于257-384位的密钥,使用SHA-384;对于 385-512 位的密钥,使用 SHA-512.必须截断哈希值,将最左边的位保留为 AES 密钥包装或使用的直接加密算法的适当位长度,例如,将A128KW的 SHA-256 哈希截断为 128 位。如果需要大于 512 位的对称密钥,则 必须通过扩展定义从client_secret派生密钥的不同方法。公共(非机密)客户端不得使用对称加密,因为它们无法保守秘密。

有关加密请求需求的安全注意事项, 请参阅第 16.21 节。 (Need for Encrypted Requests)



目录

10.2.1.非对称加密密钥的轮换

轮换加密密钥必然使用与签名密钥不同的过程,因为加密方启动该过程,因此不能依赖kids的更改作为密钥需要更改的信号。加密方仍然使用JWE中的kid标头参数来告诉解密方使用哪个私钥来解密,但是,加密方需要首先从接收者的jwks_uri位置的JWK集中提供的密钥中选择最合适的密钥

要轮换密钥,解密方可以在其jwks_uri位置发布新密钥,并从 JWK 集中删除那些正在停用的密钥。 jwks_uri应该 在响应中包含一个Cache-Control标头,其中包含max-age指令,如RFC 7234 [RFC7234]中所定义,这使得加密方能够安全缓存 JWK 集,而不必重新检索文档每个加密事件。解密方应该从jwks_uri引用的 JWK 集中删除停用的密钥 ,但在内部保留它们一段合理的时间,与缓存持续时间相协调,以便通过允许加密方有时间获取新密钥来促进密钥之间的平滑过渡。缓存持续时间还应该与新签名密钥的发布相协调,如第 10.1.1 节中所述。 (Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Caching,” June 2014.) (Rotation of Asymmetric Signing Keys)



目录

11. 离线访问

OpenID Connect 定义以下范围值来请求离线访问:

离线访问
选修的。此范围值请求颁发 OAuth 2.0 刷新令牌,该令牌可用于获取访问令牌,即使最终用户不存在(未登录),该访问令牌也会授予对最终用户的 UserInfo 端点的访问权限。

当请求离线访问时,必须使用同意的提示 参数值,除非处理请求的其他条件允许离线访问所请求的资源。 OP 必须始终获得返回刷新令牌的同意,以允许离线访问所请求的资源。先前保存的用户同意并不总是足以授予离线访问权限。

收到包含offline_access值 的范围参数后 ,授权服务器:

刷新令牌的使用并不限于 offline_access用例。授权服务器可以在超出本规范范围的其他上下文中授予刷新令牌。



目录

12. 使用刷新令牌

对令牌端点的请求还可以通过使用grant_type刷新令牌来使用刷新令牌,如 OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 6 节中所述。本部分定义使用刷新令牌时 OpenID Connect 授权服务器的行为。



目录

12.1.刷新请求

要刷新访问令牌,客户端必须使用为其client_id注册的身份验证方法对令牌端点进行身份验证,如 第 9 节 (Client Authentication)中所述。根据第 13.2 节,客户端使用表单序列化通过 HTTP POST将参数发送 到令牌端点 (Form Serialization)

以下是刷新请求的非规范示例(值内换行仅用于显示目的):

  POST /token HTTP/1.1
  Host: server.example.com
  Content-Type: application/x-www-form-urlencoded

  client_id=s6BhdRkqt3
    &client_secret=some_secret12345
    &grant_type=refresh_token
    &refresh_token=8xLOxBtZp8
    &scope=openid%20profile

授权服务器必须验证刷新令牌,必须验证它是否已颁发给客户端,并且必须验证客户端是否已成功验证其是否具有客户端身份验证方法。



目录

12.2.成功刷新响应

成功验证刷新令牌后,响应正文是第 3.1.3.3 节 (Successful Token Response)的令牌响应 ,但它可能不包含id_token

如果令牌刷新请求返回 ID 令牌,则适用以下要求:

以下是刷新响应的非规范示例:

  HTTP/1.1 200 OK
  Content-Type: application/json
  Cache-Control: no-store

  {
   "access_token": "TlBN45jURg",
   "token_type": "Bearer",
   "refresh_token": "9yNOxJtZa5",
   "expires_in": 3600
  }


目录

12.3.刷新错误响应

如果刷新请求无效或未经授权,授权服务器将返回OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 5.2 节中定义的令牌错误响应。



目录

13. 序列化

使用以下方法之一序列化消息:

  1. 查询字符串序列化
  2. 表单序列化
  3. JSON序列化

本节描述这些序列化方法的语法;其他部分描述了何时可以并且必须使用它们。请注意,并非所有方法都可用于所有消息。



目录

13.1.查询字符串序列化

为了使用查询字符串序列化来序列化参数,客户端通过使用[W3C.SPSD-定义的application/x-www-form-urlencoded格式] 将参数和值添加到 URL 的查询组件来构造字符串。 html401-20180327] (, “HTML 4.01 Specification,” March 2018.)。查询字符串序列化通常用在 HTTP GET请求中。向 URL 的片段组件添加参数时也使用相同的序列化方法。

以下是此序列化的非规范示例(值内换行仅用于显示目的):

  GET /authorize?
    response_type=code
    &scope=openid
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
  Host: server.example.com


目录

13.2.表单序列化

参数及其值通过使用[W3C.SPSD-html401-20180327]定义的application/x-www-form-urlencoded格式将参数名称和值添加到 HTTP 请求的实体正文来进行表单序列化。表单序列化通常用在 HTTP POST请求中。 (, “HTML 4.01 Specification,” March 2018.)

以下是此序列化的非规范示例(值内换行仅用于显示目的):

  GET /authorize?
    response_type=code
    &scope=openid
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb HTTP/1.1
  Host: server.example.com


目录

13.3. JSON序列化

通过在最高结构级别添加每个参数,参数被序列化为 JSON 对象结构。参数名称和字符串值表示为 JSON 字符串。数值表示为 JSON 数字。布尔值表示为 JSON 布尔值。除非另有说明,省略的参数和没有值的参数应该从对象中省略,并且不使用 JSON null值表示。参数可以将 JSON 对象或 JSON 数组作为其值。

以下是此序列化的非规范示例:

  {
   "access_token": "SlAV32hkKG",
   "token_type": "Bearer",
   "expires_in": 3600,
   "refresh_token": "8xLOxBtZp8"
  }


目录

14. 字符串操作

处理某些 OpenID Connect 消息需要将消息中的值与已知值进行比较。例如,UserInfo 端点返回的声明名称可能会与特定的声明名称(例如sub )进行比较。然而,比较 Unicode [UNICODE] (The Unicode Consortium, “The Unicode Standard,” .)字符串具有重大的安全隐患。

因此,JSON 字符串和其他 Unicode 字符串之间的比较必须按如下指定进行:

  1. 删除任何应用转义的 JSON 以生成 Unicode 代码点数组。
  2. Unicode 规范化[USA15] (Whistler, K., “Unicode Normalization Forms,” August 2023.)不得在任何时候应用于 JSON 字符串或要与之比较的字符串。
  3. 两个字符串之间的比较必须作为 Unicode 代码点到代码点相等性比较来执行。

在多个地方,本规范使用空格分隔的字符串列表。在所有此类情况下,必须使用单个 ASCII 空格字符 (0x20) 作为分隔符。



目录

15. 实施注意事项

该规范定义了依赖方和 OpenID 提供商使用的功能。预计某些 OpenID 提供商将需要使用它们的 RP 进行静态带外配置,而其他提供商将支持 RP 的动态使用,而无需在它们之间预先建立关系。因此,OP 的强制实现功能分为两组:第一组适用于所有 OP,第二组适用于“动态”OpenID 提供商。



目录

15.1.必须为所有 OpenID 提供商实施功能

所有 OpenID 提供商必须实现本规范中定义的以下功能。该列表补充了已在其他地方列出为“必需”或用“必须”描述的功能集,因此其本身并不是 OP 的一组全面的实现要求。

使用 RSA SHA-256 签署 ID 令牌
OP 必须支持使用 RSA SHA-256 算法(alg值为 RS256)签名 ID 令牌,除非 OP 仅支持从令牌端点返回 ID 令牌(如授权代码流的情况)并且仅允许客户端注册指定 none作为请求的 ID 令牌签名算法。
提示参数
OP 必须支持提示参数,如第 3.1.2 节 (Authorization Endpoint)中所定义,包括指定的用户界面行为,例如nonelogin
显示参数
OP 必须支持显示参数,如第 3.1.2 节 (Authorization Endpoint)中定义。 (请注意,此参数所需的最低支持级别只是其使用不得导致错误。)
首选区域设置
OP 必须通过ui_localesClaims_locales请求参数 支持用户界面和声明的首选语言和脚本的请求 ,如第 3.1.2 节 (Authorization Endpoint)中所定义。 (请注意,这些参数所需的最低支持级别只是使其使用不会导致错误。)
认证时间
OP 必须支持根据请求返回最终用户通过auth_time声明 进行身份验证的时间,如第 2 节 (ID Token)中所定义。
最大认证年龄
OP 必须支持通过max_age参数 强制执行最大身份验证期限,如第 3.1.2 节 (Authorization Endpoint)中所定义。
身份验证上下文类参考
OP 必须通过acr_values参数 支持对特定身份验证上下文类参考值的请求,如第 3.1.2 节 (Authorization Endpoint)中所定义。 (请注意,此参数所需的最低支持级别只是使其使用不会导致错误。)



目录

15.2.强制实施动态 OpenID 提供商的功能

除了上面列出的功能之外,支持与没有预先配置关系的 RP 动态建立关系的 OpenID 提供商还必须实现本规范和相关规范中定义的以下功能。

响应类型
这些 OpenID 提供者必须支持 id_token响应类型,所有非自行发布的 OP 也必须支持 代码id_token 令牌响应类型。
发现
这些 OP 必须支持 Discovery,如 OpenID Connect Discovery 1.0 (Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” December 2023.) [OpenID.Discovery] 中所定义。
动态注册
这些 OP 必须支持动态客户端注册,如 OpenID Connect 动态客户端注册 1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.) [OpenID.Registration] 中所定义。
用户信息端点
所有发出访问令牌的动态 OP 必须支持 UserInfo 端点,如第 5.3 节 (UserInfo Endpoint)中所定义。 (自行颁发的 OP 不颁发访问令牌。)
公钥作为裸密钥发布
这些 OP 必须将其公钥发布为裸 JWK 密钥(也可能附有这些密钥的 X.509 表示形式)。
请求URI
这些 OP 必须支持使用请求对象值发出的请求,该值是从请求 URI 中检索的,该请求 URI 是通过request_uri参数提供的,如第 6.2 节 (Passing a Request Object by Reference)中所定义。



目录

15.3.发现和注册

某些 OpenID Connect 安装可以使用一组预先配置的 OpenID 提供商和/或依赖方。在这些情况下,可能不需要支持有关身份或服务的信息的动态发现或客户端的动态注册。

但是,如果安装选择支持依赖方和没有预先配置关系的 OpenID 提供商之间的意外交互,则它们应该通过实施OpenID Connect Discovery 1.0 (Sakimura, N., Bradley, J., Jones, M., and E. Jay, “OpenID Connect Discovery 1.0,” December 2023.) [OpenID.Discovery] 和OpenID Connect 动态客户端注册中定义的设施来实现此目的1.0 (Sakimura, N., Bradley, J., and M. Jones, “OpenID Connect Dynamic Client Registration 1.0,” December 2023.) [OpenID.Registration] 规范。



目录

15.4.必须为依赖方实施功能

一般来说,依赖方在与 OpenID 提供商交互时使用哪些功能取决于依赖方。但是,某些选择取决于其 OAuth 客户端的性质,例如是否是能够保守秘密的机密客户端(在这种情况下,授权代码流可能是合适的),或者是否是公共客户端,例如,基于用户代理的应用程序或静态注册的本机应用程序,在这种情况下,隐式流可能是合适的。

使用 OpenID Connect 功能时,依赖方使用时,那些列为“必需”或用“必须”描述的功能是强制实施的。同样,那些被描述为“可选”的功能不需要使用或支持,除非它们在特定的应用程序上下文中提供价值。最后,当与支持 Discovery 的 OpenID Provider 交互时,OP 的 Discovery 文档可用于动态确定哪些 OP 功能可供 RP 使用。



目录

15.5.实施说明



目录

15.5.1.授权码实施说明

使用授权代码或混合流时,令牌端点会返回 ID 令牌,以响应使用授权代码的令牌请求。某些实现可能会选择对要在授权代码值中返回的 ID 令牌的状态进行编码。其他人可以使用授权代码值作为存储该状态的数据库的索引。



目录

15.5.2.随机数实施说明

nonce参数 值需要包含每个会话的状态并且攻击者无法猜测。 Web 服务器客户端实现此目的的一种方法是将加密随机值存储为 HttpOnly 会话 cookie,并使用该值的加密哈希作为随机数参数。在这种情况下,将返回的 ID 令牌中的随机数与会话 cookie 的哈希值进行比较,以检测第三方的 ID 令牌重放。适用于 JavaScript 客户端和其他基于浏览器的客户端的相关方法是将加密随机值存储在 HTML5 本地存储中,并使用该值的加密哈希。



目录

15.5.3.重定向 URI 片段处理实施说明

当重定向 URI 片段值中返回响应参数时,客户端需要让用户代理解析片段编码值并将它们传递给客户端的处理逻辑以供使用。例如,可以直接访问加密 API 的用户代理可以是独立的,所有客户端代码都用 JavaScript 编写。

但是,如果客户端不完全在用户代理中运行,实现此目的的一种方法是将它们发布到 Web 服务器客户端进行验证。

以下是客户端可能在其 redirect_uri托管的JavaScript 文件的示例。这是通过授权服务器的重定向加载的。片段组件被解析,然后通过POST发送到 URI,该 URI 将验证并使用收到的信息。

以下是重定向 URI 响应的非规范示例:

  GET /cb HTTP/1.1
  Host: client.example.org

  HTTP/1.1 200 OK
  Content-Type: text/html

  <script type="text/javascript">

  // First, parse the query string
  var params = {}, postBody = location.hash.substring(1),
      regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(postBody)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  // And send the token over to the server
  var req = new XMLHttpRequest();
  // using POST so query isn't logged
  req.open('POST', 'https://' + window.location.host +
                   '/catch_response', true);
  req.setRequestHeader('Content-Type',
                       'application/x-www-form-urlencoded');

  req.onreadystatechange = function (e) {
    if (req.readyState == 4) {
      if (req.status == 200) {
  // If the response from the POST is 200 OK, perform a redirect
        window.location = 'https://'
          + window.location.host + '/redirect_after_login'
      }
  // if the OAuth response is invalid, generate an error message
      else if (req.status == 400) {
        alert('There was an error processing the token')
      } else {
        alert('Something other than 200 was returned')
      }
    }
  };
  req.send(postBody);


目录

15.6.兼容性说明

注意:本规范原始版本中先前描述的潜在兼容性问题现已得到解决。



目录

15.7.相关规范和实施者指南

这些相关的可选规范可以与本规范结合使用以提供附加功能:

这些实施者指南旨在为基本网络依赖方的实施者提供独立的参考:



目录

16. 安全考虑

本规范引用了OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 10 节和OAuth 2.0 承载令牌使用 (Jones, M. and D. Hardt, “The OAuth 2.0 Authorization Framework: Bearer Token Usage,” October 2012.)[RFC6750]第 5 节 中定义的安全注意事项。此外,OAuth 2.0 威胁模型和安全注意事项 (Lodderstedt, T., Ed., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.)[RFC6819] 规范提供了适用于该规范的广泛威胁和控制列表,因为它基于 OAuth 2.0. ISO/IEC 29115 (International Organization for Standardization, “ISO/IEC 29115:2013. Information technology - Security techniques - Entity authentication assurance framework,” April 2013.) [ISO29115] 还提供了实施者需要考虑的威胁和控制措施。强烈建议实施者详细阅读这些参考文献并应用其中描述的对策。

此外,还考虑了以下攻击向量和补救措施列表。



目录

16.1.要求披露

如果不采取适当的措施,请求可能会泄露给攻击者,从而构成安全和隐私威胁。

除了[RFC6819]第5.1.1节中所述之外,该标准还提供了一种通过使用 (Lodderstedt, T., Ed., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.)requestrequest_uri参数来提供请求端到端机密性的方法,其中请求 的内容 是加密的JWT使用适当的密钥和密码。在间接请求的情况下,这甚至可以防止用户代理受到损害。



目录

16.2.服务器伪装

恶意服务器可能会使用各种手段伪装成合法服务器。为了检测此类攻击,客户端需要对服务器进行身份验证。

除了[RFC6819] (Lodderstedt, T., Ed., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.)第 5.1.2 节中所述的内容之外,该标准还提供了一种通过使用带有适当密钥和密码的签名或加密 JWT 来对服务器进行身份验证的方法。



目录

16.3.代币制造/修改

攻击者可能会生成虚假令牌或修改现有可解析令牌的令牌内容(例如声明值或签名),从而导致 RP 向客户端授予不适当的访问权限。例如,攻击者可能会修改可解析令牌以延长有效期;客户端可能会修改可解析令牌以访问他们不应查看的信息。

有两种方法可以减轻这种攻击:

  1. 该令牌可以由 OP 进行数字签名。依赖方应该验证数字签名以验证它是由合法的 OP 颁发的。
  2. 令牌可以通过受保护的通道(例如 TLS)发送。有关使用 TLS 的更多信息,请参阅第 16.17 节 (TLS Requirements)。在本规范中,令牌始终通过 TLS 保护的通道发送。但请注意,该措施仅是针对第三方攻击者的防御,不适用于客户端为攻击者的情况。



目录

16.4.访问令牌披露

访问令牌是用于访问受保护资源的凭证,如 OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 第 1.4 节中所定义。访问令牌代表最终用户的授权,不得暴露给未经授权的各方。



目录

16.5.服务器响应披露

服务器响应可能包含身份验证数据和包含敏感客户端信息的声明。泄露响应内容可能会使客户端容易受到其他类型的攻击。

可以通过以下两种方式缓解服务器响应泄露:

  1. 使用代码响应类型。响应通过 TLS 保护通道发送,其中客户端通过 client_id client_secret 进行身份验证。
  2. 对于其他响应类型,可以使用客户端的公钥或共享密钥对签名响应进行加密,作为具有适当密钥和密码的加密 JWT。



目录

16.6.服务器响应拒绝

如果没有适当的机制,服务器可能会拒绝响应。例如,如果服务器不对响应进行数字签名,则服务器可以声明该响应不是通过服务器的服务生成的。

为了减轻这种威胁,服务器可以使用支持不可否认性的密钥对响应进行数字签名。客户端应该验证数字签名,以验证它是由合法服务器颁发的并且其完整性完好无损。



目录

16.7.请求拒绝

由于受损或恶意的客户端可能会向错误的一方发送请求,因此仅使用不记名令牌进行身份验证的客户端可以拒绝任何交易。

为了减轻这种威胁,服务器可以要求客户端使用支持不可否认性的密钥对请求进行数字签名。服务器应该验证数字签名,以验证它是由合法客户端颁发的并且其完整性完好无损。



目录

16.8.访问令牌重定向

攻击者使用为一个资源生成的访问令牌来获取对第二个资源的访问权限。

为了减轻这种威胁,访问令牌应该受到受众和范围的限制。实现它的一种方法是包含为其生成该资源作为受众的资源的标识符。资源验证传入令牌是否包含其标识符作为令牌的受众。



目录

16.9.代币重用

攻击者尝试使用一次性使用令牌,例如已经在目标资源中使用过一次的授权代码。为了减轻这种威胁,令牌应该包含时间戳和较短的有效期。然后依赖方检查时间戳和生命周期值以确保令牌当前有效。

或者,服务器可以记录令牌的使用状态并检查每个请求的状态。



目录

16.10.窃听或泄露授权码(辅助验证器捕获)

除了[RFC6819] (Lodderstedt, T., Ed., McGloin, M., and P. Hunt, “OAuth 2.0 Threat Model and Security Considerations,” January 2013.)第 4.4.1.1 节中描述的攻击模式之外,如果用户代理被恶意软件感染,则可以在用户代理中捕获授权代码,其中 TLS 会话将终止。但是,只要使用客户端身份验证或加密响应,捕获它就没有用。



目录

16.11.代币替代

令牌替换是一类攻击,其中恶意用户交换各种令牌,包括将合法用户的授权代码与攻击者拥有的另一个令牌交换。实现这一目标的一种方法是,攻击者从一个会话中复制一个令牌,并在另一个会话的 HTTP 消息中使用它,当浏览器可以使用该令牌时,这很容易做到;这称为“剪切和粘贴”攻击。

OAuth 2.0 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.) [RFC6749] 的隐式流程并不是为了减轻这种风险而设计的。在第 10.16 节中,它规范地要求任何使用授权过程作为委托给客户端的最终用户身份验证的形式,不得使用隐式流程,而不采用额外的安全机制,使客户端能够确定 ID 令牌和访问令牌是否已发行供其使用。

在 OpenID Connect 中,可以通过 ID 令牌提供的机制来缓解这种情况。 ID Token 是一个签名的安全令牌,提供诸如 iss(发行者)、 sub(主题)、 aud(受众)、 at_hash(访问令牌哈希)和 c_hash(代码哈希)等声明。使用 ID 令牌,客户端能够检测令牌替换攻击。

ID 令牌中的c_hash 使客户端能够防止授权代码替换。 ID 令牌中的 at_hash使客户端能够防止访问令牌替换。

此外,恶意用户可能会尝试通过破坏授权端点和客户端之间或令牌端点和客户端之间的通信通道来冒充更高特权的用户,例如通过交换授权代码或重新排序消息,以说服令牌端点:攻击者的授权对应于代表更高权限的用户发送的授权。

对于本规范定义的 HTTP 绑定,对令牌请求的响应按照 HTTP 中的消息顺序绑定到相应的请求,因为包含令牌的响应和请求都受 TLS 保护,TLS 会检测并防止数据包重新排序。

当设计此规范的另一个绑定到无法将令牌端点请求强绑定到响应的协议时,必须利用其他机制来解决此问题。一种这样的机制可能是 在令牌请求和响应中 包含带有c_hash声明的 ID 令牌。



目录

16.12.定时攻击

定时攻击使攻击者能够通过成功和不成功的解密操作或成功和不成功的消息签名验证所采用的代码路径中经过的时间差来获取不必要的大量信息。它可用于减少所用密码的有效密钥长度。

实现不应在发现错误时终止验证过程,而应继续运行,直到处理完所有八位字节以避免这种攻击。



目录

16.13.其他与加密相关的攻击

根据加密和签名/完整性检查所使用的方法,可能存在各种与加密相关的攻击。实施者需要查阅JWT (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.) [JWT] 规范及其引用的规范的安全注意事项,以避免这些规范中发现的漏洞。



目录

16.14.签名和加密订单

在许多司法管辖区,加密文本签名被视为无效。因此,为了完整性和不可否认性,本规范要求在执行签名时对纯文本 JSON 声明进行签名。如果同时需要签名和加密,则在包含签名声明的 JWS 上执行签名和加密,结果是嵌套 JWT,如[JWT] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)中指定的。请注意,由于所有 JWE 加密算法都提供完整性保护,因此无需单独对加密内容进行签名。



目录

16.15.发行人标识符

OpenID Connect 支持每个主机和端口组合有多个颁发者。发现返回的颁发者必须与 ID 令牌中 iss的值完全匹配 。

OpenID Connect 将任何颁发者 URI 的路径组件视为颁发者标识符的一部分。例如,发行者标识符为“https://example.com”的主题“1234”不等同于发行者标识符为“https://example.com/sales”的主题“1234”。

建议每个主机仅使用一个发行者。但是,如果主机支持多个租户,则该主机可能需要多个颁发者。



目录

16.16.隐式流量威胁

在隐式流程中,访问令牌通过 HTTPS 在客户端的redirect_uri的片段组件中返回,因此它在 OP 和用户代理之间以及用户代理和 RP 之间受到保护。唯一可以捕获它的地方是 TLS 会话终止的用户代理,如果用户代理被恶意软件感染或受到恶意方的控制,则可能会发生这种情况。



目录

16.17. TLS 要求

实现必须支持 TLS。应该实施哪个版本会随着时间的推移而变化,并且取决于实施时的广泛部署和已知的安全漏洞。实施应遵循 BCP 195 [RFC8996] (Moriarty, K. and S. Farrell, “Deprecating TLS 1.0 and TLS 1.1,” March 2021.) [RFC9325] (Sheffer, Y., Saint-Andre, P., and T. Fossati, “Recommendations for Secure Use of Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS),” November 2022.)中的指南,该指南提供了提高使用 TLS 的已部署服务的安全性的建议和要求。

为了防止信息泄露和篡改,必须使用 TLS 以及提供机密性和完整性保护的密码套件来应用机密性保护。

每当使用 TLS 时,都必须根据RFC 6125 (Saint-Andre, P. and J. Hodges, “Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS),” March 2011.) [RFC6125] 执行 TLS 服务器证书检查。



目录

16.18.访问令牌和刷新令牌的生命周期

授权服务器可能无法撤销访问令牌。因此,访问令牌的生命周期应保持为一次性使用或非常短的生命周期。

如果需要持续访问 UserInfo 端点或其他受保护资源,则可以使用刷新令牌。然后,客户端可以在令牌端点将刷新令牌交换为可用于访问资源的新的短期访问令牌。

授权服务器应该在授权期间清楚地识别对用户的长期授权。授权服务器应该为最终用户提供一种机制来撤销授予客户端的访问令牌和刷新令牌。



目录

16.19.对称密钥熵

第 10.1 节 (Signing)第 10.2 节 (Encryption)中,密钥是从client_secret值派生的。因此,当与对称签名或加密操作一起使用时, client_secret值必须包含足够的熵来生成加密强密钥。此外,client_secret值还必须至少包含所使用的特定算法的 MAC 密钥所需的最小八位字节数。例如,对于HS256client_secret值必须包含至少 32 个八位字节(并且几乎肯定应该包含更多,因为client_secret值可能使用受限制的字母表)。



目录

16.20.需要签署请求

在某些情况下,客户端可能需要使用签名请求来确保所需的请求参数在不被篡改的情况下传递到 OP。例如,max_ageacr_values可以更好地保证在签名请求中传递时执行的身份验证的性质。



目录

16.21.需要加密请求

在某些情况下,了解 OpenID Connect 请求的内容本身就可能泄露有关最终用户的敏感信息。例如,知道客户正在请求特定的声明或请求使用特定的身份验证方法可能会泄露有关最终用户的敏感信息。 OpenID Connect 允许对 OpenID 提供商的请求进行加密,以防止此类潜在敏感信息被泄露。



目录

16.22. HTTP 307 重定向

HTTP 307 重定向将 POST 请求发送到被重定向到的一方,其中包含先前请求中的所有表单数据。这可能会将用于 OpenID 提供商的凭证泄露给依赖方。因此,重定向到重定向 URI 时不得使用 HTTP 307 重定向。同样,虽然 HTTP 302 重定向通常以不执行此操作的方式实现,但最好使用 HTTP 303 重定向,因为它被定义为不执行此操作。



目录

16.23. iOS 上的自定义 URI 方案

请注意,在 iOS 上,多个应用程序可以注册为自定义 URI 方案的处理程序,因此无法确定调用应用程序是否会收到来自自发行 OpenID 提供商的身份验证回复。使用声明的 URI 是使用openid:自定义 URI 方案的替代方法。

虽然可以将处理程序分配给自定义 URI 方案,并且操作系统可能可以帮助最终用户选择正确的处理程序,但无法保证给定自定义 URI 方案的处理程序不会被替换随后安装的本机应用程序。截至撰写本文时,似乎还没有针对此漏洞的万无一失的缓解措施。



目录

17. 隐私考虑



目录

17.1.个人身份信息

UserInfo 响应通常包含个人身份信息 (PII)。因此,为特定目的发布信息应根据相关规定在授权时间或之前获得最终用户的同意。使用目的通常与redirect_uris相关联进行注册。

仅必要的用户信息数据应存储在客户端,并且客户端应将接收到的数据与使用目的声明相关联。



目录

17.2.数据访问监控

资源服务器应该使最终用户的用户信息访问日志可供他们使用,以便他们可以监视谁访问了他们的数据。



目录

17.3.相关性

为了保护最终用户免受客户端之间可能存在的关联的影响,应考虑 使用成对假名标识符(PPID)作为 子(主题)。



目录

17.4. 离线访问

离线访问允许在用户不在场时访问声明,这比用户在场时的声明传输带来更大的隐私风险。因此,离线访问资源时应谨慎获取明确同意。本规范强制要求使用提示 参数来获得同意,除非已知请求符合每个司法管辖区处理请求的条件。

当使用隐式流或混合流通过用户代理返回访问令牌时,它暴露给攻击者的风险更大,攻击者稍后可以使用它来访问 UserInfo 端点。如果Access Token不支持离线访问,并且服务器可以区分Client请求是离线还是在线,那么风险将大大降低。因此,本规范要求在通过用户代理传输访问令牌时忽略离线访问请求。请注意,区分服务器的在线和离线访问可能很困难,尤其是对于本机客户端而言。服务器很可能不得不依赖启发式方法。此外,对于代码令牌令牌的响应类型,通过用户代理传递的访问令牌的暴露风险 是相同的。因此,实现应该准备好检测访问令牌是通过用户代理还是直接从令牌端点颁发,如果令牌是通过用户代理颁发,则拒绝离线访问。

请注意,尽管这些规定要求通过提示参数 进行明确的同意对话,但仅用户按下“接受”按钮等事实可能并不构成有效的同意。开发人员应该意识到,为了使同意行为有效,通常,最终用户必须理解条款的影响,同意必须是自由给出的,而不是强迫的(即必须有其他选项) ,并且条款必须公平公正。一般来说,建议服务遵循每个司法管辖区所需的隐私原则,并依靠其他条件来处理请求,而不仅仅是简单的明确同意,因为在线自助服务的“明确同意”在某些情况下通常不构成有效同意。司法管辖区。



目录

18. IANA 考虑因素



目录

18.1. JSON Web 令牌声明注册

本规范在[JWT] 建立的IANA“JSON Web 令牌声明”注册表[IANA.JWT.Claims] (IANA, “JSON Web Token Claims,” .) 中注册了以下声明 (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Token (JWT),” May 2015.)



目录

18.1.1.注册表内容



目录

18.2. OAuth 参数注册

本规范在RFC 6749 [RFC6749] 建立的IANA“OAuth 参数”注册表[IANA.OAuth.Parameters] (IANA, “OAuth Parameters,” .) 中注册了以下参数。 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.)



目录

18.2.1.注册表内容



目录

18.3. OAuth 扩展错误注册

本规范在RFC 6749 [RFC6749] 建立的IANA“OAuth 扩展错误”注册表[IANA.OAuth.Parameters] (IANA, “OAuth Parameters,” .) 中注册了以下错误。 (Hardt, D., Ed., “The OAuth 2.0 Authorization Framework,” October 2012.)



目录

18.3.1.注册表内容



目录

18.4. URI 方案注册

本规范在RFC 7595 [RFC7595] 建立的IANA“统一资源标识符 (URI) 方案”注册表[IANA.URISchemes] (IANA, “Uniform Resource Identifier (URI) Schemes,” .) 中注册以下 URI 方案。 (Thaler, D., Ed., Hansen, T., and T. Hardie, “Guidelines and Registration Procedures for URI Schemes,” June 2015.)



目录

18.4.1.注册表内容



目录

19. 参考文献



目录

19.1.规范性参考文献

[CORS] Opera Software ASA,“跨源资源共享”,2010 年 7 月。
[E.164] 国际电信联盟,“ E.164:国际公共电信编号计划”,2010 年。
[IANA.AMR] IANA,“身份验证方法参考值”。
[IANA.JWT.声明] IANA,“ JSON Web 令牌声明”。
[IANA.语言] IANA,“语言子标签注册表”。
[IANA.OAuth.参数] IANA,“ OAuth 参数”。
[IANA.URI 方案] IANA,“统一资源标识符 (URI) 方案。”
[IANA.时区] IANA,“时区数据库”。
[ISO29115] 国际标准化组织,“ ISO/IEC 29115:2013.信息技术 - 安全技术 - 实体认证保证框架”,ISO/IEC 29115:2013,2013 年 4 月。
[ISO3166-1] 国际标准化组织,“ ISO 3166-1:2020.国家及其分区名称的表示代码 - 第 1 部分:国家/地区代码,”2020 年 8 月。
[ISO639] 国际标准化组织,“ ISO 639:2023.个别语言和语言组的代码”,2023 年 11 月。
[ISO8601-1] 国际标准化组织,“ ISO 8601-1:2019/Amd 1:2022.日期和时间 - 信息交换的表示 - 第 1 部分:基本规则”,2022 年 10 月。
[JWA] Jones, M.,“ JSON Web 算法 (JWA) ”,RFC 7518,DOI 10.17487/RFC7518,2015 年 5 月。
[JWE] Jones, M. 和 J. Hildebrand,“ JSON Web 加密 (JWE) ”,RFC 7516,DOI 10.17487/RFC7516,2015 年 5 月。
[JWK] Jones, M.,“ JSON Web 密钥 (JWK) ”,RFC 7517,DOI 10.17487/RFC7517,2015 年 5 月。
[JWS] Jones, M.、Bradley, J. 和 N. Sakimura,“ JSON Web 签名 (JWS) ”,RFC 7515,DOI 10.17487/RFC7515,2015 年 5 月。
[智威汤逊] Jones, M.、Bradley, J. 和 N. Sakimura,“ JSON Web 令牌 (JWT) ”,RFC 7519,DOI 10.17487/RFC7519,2015 年 5 月。
[OAuth.断言] Campbell, B.、Mortimore, C.、Jones, M. 和 Y. Goland,“ OAuth 2.0 客户端身份验证和授权的断言框架”,RFC 7521,DOI 10.17487/RFC7521,2015 年 5 月。
[OAuth.JWT] Jones, M.、Campbell, B. 和 C. Mortimore,“ OAuth 2.0 客户端身份验证和授权授予的 JSON Web 令牌 (JWT) 配置文件”,RFC 7523,DOI 10.17487/RFC7523,2015 年 5 月。
[OAuth.响应] de Medeiros, B., Ed.、Scurtescu, M.、Tarjan, P. 和 M. Jones,“ OAuth 2.0 多重响应类型编码实践”,2014 年 2 月。
[OpenID.发现] Sakimura, N.、Bradley, J.、Jones, M. 和 E. Jay,“ OpenID Connect Discovery 1.0 ”,2023 年 12 月。
[OpenID.注册] Sakimura, N.、Bradley, J. 和 M. Jones,“ OpenID Connect 动态客户端注册 1.0 ”,2023 年 12 月。
[RFC20] Cerf, V.,“网络交换的 ASCII 格式”,STD 80,RFC 20,DOI 10.17487/RFC0020,1969 年 10 月。
[RFC2119] Bradner, S.,“ RFC 中用于指示需求级别的关键字”,BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997 年 3 月。
[RFC3339] Klyne, G. 和 C. Newman,“互联网上的日期和时间:时间戳”,RFC 3339,DOI 10.17487/RFC3339,2002 年 7 月。
[RFC3629] Yergeau, F.,“ UTF-8,ISO 10646 的转换格式”,STD 63,RFC 3629,DOI 10.17487/RFC3629,2003 年 11 月。
[RFC3966] Schulzrinne, H.,“电话号码的 tel URI ”,RFC 3966,DOI 10.17487/RFC3966,2004 年 12 月。
[RFC3986] Berners-Lee, T.、Fielding, R. 和 L. Masinter,“统一资源标识符 (URI):通用语法”,STD 66,RFC 3986,DOI 10.17487/RFC3986,2005 年 1 月。
[RFC5322] Resnick, P., Ed.,“互联网消息格式”,RFC 5322,DOI 10.17487/RFC5322,2008 年 10 月。
[RFC5646] 菲利普斯,A.,埃德。和 M. Davis,Ed.,“用于识别语言的标签”,BCP 47,RFC 5646,DOI 10.17487/RFC5646,2009 年 9 月。
[RFC6125] Saint-Andre, P. 和 J. Hodges,“在传输层安全 (TLS) 环境中使用 X.509 (PKIX) 证书表示和验证互联网公钥基础设施中基于域的应用程序服务身份”,RFC 6125, DOI 10.17487/RFC6125,2011 年 3 月。
[RFC6711] Johansson, L.,“ IANA 保证级别 (LoA) 配置文件注册机构”,RFC 6711,DOI 10.17487/RFC6711,2012 年 8 月。
[RFC6749] Hardt, D., Ed.,“ OAuth 2.0 授权框架”,RFC 6749,DOI 10.17487/RFC6749,2012 年 10 月。
[RFC6750] Jones, M. 和 D. Hardt,“ OAuth 2.0 授权框架:不记名令牌使用”,RFC 6750,DOI 10.17487/RFC6750,2012 年 10 月。
[RFC6819] Lodderstedt, T., Ed.、McGloin, M. 和 P. Hunt,“ OAuth 2.0 威胁模型和安全注意事项”,RFC 6819,DOI 10.17487/RFC6819,2013 年 1 月。
[RFC7230] Fielding, R., Ed. 和 J. Reschke, Ed.,“超文本传输​​协议 (HTTP/1.1):消息语法和路由”,RFC 7230,DOI 10.17487/RFC7230,2014 年 6 月。
[RFC7231] 菲尔丁,R.,埃德。和 J. Reschke,Ed.,“超文本传输​​协议 (HTTP/1.1):语义和内容”,RFC 7231,DOI 10.17487/RFC7231,2014 年 6 月。
[RFC7234] Fielding, R., Ed.、Nottingham, M., 和 J. Reschke, Ed.,“超文本传输​​协议 (HTTP/1.1):缓存”,RFC 7234,DOI 10.17487/RFC7234,2014 年 6 月。
[RFC8176] Jones, M.、Hunt, P. 和 A. Nadalin,“身份验证方法参考值”,RFC 8176,DOI 10.17487/RFC8176,2017 年 6 月。
[RFC8259] Bray, T., Ed.,“ JavaScript 对象表示法 (JSON) 数据交换格式”,STD 90、RFC 8259、DOI 10.17487/RFC8259,2017 年 12 月。
[RFC8996] Moriarty, K. 和 S. Farrell,“弃用 TLS 1.0 和 TLS 1.1 ”,BCP 195、RFC 8996、DOI 10.17487/RFC8996,2021 年 3 月。
[RFC9325] Sheffer, Y.、Saint-Andre, P. 和 T. Fossati,“安全使用传输层安全 (TLS) 和数据报传输层安全 (DTLS) 的建议”,BCP 195、RFC 9325、DOI 10.17487/RFC9325, 2022 年 11 月。
[统一码] Unicode 联盟,“ Unicode 标准”。
[美国15] Whistler, K.,“ Unicode 规范化形式”,Unicode 标准附件 15,2023 年 8 月。
[W3C.SPSD-html401-20180327] HTML 4.01 规范”,W3C REC SPSD-html401-20180327,W3C SPSD-html401-20180327,2018 年 3 月。


目录

19.2.参考资料丰富

[JWK.指纹] Jones, M. 和 N. Sakimura,“ JSON Web 密钥 (JWK) 指纹”,RFC 7638,DOI 10.17487/RFC7638,2015 年 9 月。
[OAuth.Post] Jones, M. 和 B. Campbell,“ OAuth 2.0 表单后响应模式”,2015 年 4 月。
[OpenID.2.0] OpenID 基金会,“ OpenID 身份验证 2.0 ”,2007 年 12 月。
[OpenID.BackChannel] Jones, M. 和 J. Bradley,“ OpenID Connect 反向通道注销 1.0 ”,2023 年 12 月。
[OpenID.基本] Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“ OpenID Connect 基本客户端实施者指南 1.0 ”,2023 年 12 月。
[OpenID.Core.勘误1] Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“ OpenID Connect Core 1.0 包含勘误表集 1 ”,2014 年 11 月。
[OpenID.Core.Final] Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“ OpenID Connect Core 1.0(最终版) ”,2014 年 2 月。
[OpenID.FrontChannel] Jones, M.,“ OpenID Connect 前端注销 1.0 ”,2022 年 9 月。
[OpenID.隐式] Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“ OpenID Connect 隐式客户端实施者指南 1.0 ”,2023 年 12 月。
[OpenID.PAPE] Recordon, D.、Jones, M.、Bufu, J.、Ed.、Daugherty, J.、Ed. 和 N. Sakimura,“ OpenID 提供商身份验证策略扩展 1.0 ”,2008 年 12 月。
[OpenID.RP发起] Jones, M.、de Medeiros, B.、Agarwal, N.、Sakimura, N. 和 J. Bradley,“ OpenID Connect RP 发起的注销 1.0 ”,2022 年 9 月。
[OpenID.会话] de Medeiros, B.、Agarwal, N.、Sakimura, N.、Bradley, J. 和 M. Jones,“ OpenID Connect 会话管理 1.0 ”,2022 年 9 月。
[RFC4949] Shirey, R.,“互联网安全术语表,版本 2 ”,FYI 36,RFC 4949,DOI 10.17487/RFC4949,2007 年 8 月。
[RFC7595] Thaler, D., Ed.、Hansen, T. 和 T. Hardie,“ URI 方案指南和注册程序”,BCP 35,RFC 7595,DOI 10.17487/RFC7595,2015 年 6 月。
[RFC9101] Sakimura, N.、Bradley, J. 和 M. Jones,“ OAuth 2.0 授权框架:JWT 安全授权请求 (JAR) ”,RFC 9101,DOI 10.17487/RFC9101,2021 年 8 月。
[X.1252] 国际电信联盟,“ ITU-T 建议 X.1252 - 网络空间安全 - 身份管理 - 基线身份管理术语和定义”,ITU-T X.1252,2010 年 4 月。


目录

附录 A. 授权示例

以下是具有不同response_type值及其响应的授权请求的非规范示例(值内换行仅用于显示目的):



目录

A.1.使用response_type=code 的示例

  GET /authorize?
    response_type=code
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb?
    code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk
    &state=af0ifjsldkj


目录

A2.使用response_type=id_token的示例

  GET /authorize?
    response_type=id_token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.
    ewogImlzcyI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAic3ViIjog
    IjI0ODI4OTc2MTAwMSIsCiAiYXVkIjogInM2QmhkUmtxdDMiLAogIm5vbmNlIjog
    Im4tMFM2X1d6QTJNaiIsCiAiZXhwIjogMTMxMTI4MTk3MCwKICJpYXQiOiAxMzEx
    MjgwOTcwLAogIm5hbWUiOiAiSmFuZSBEb2UiLAogImdpdmVuX25hbWUiOiAiSmFu
    ZSIsCiAiZmFtaWx5X25hbWUiOiAiRG9lIiwKICJnZW5kZXIiOiAiZmVtYWxlIiwK
    ICJiaXJ0aGRhdGUiOiAiMDAwMC0xMC0zMSIsCiAiZW1haWwiOiAiamFuZWRvZUBl
    eGFtcGxlLmNvbSIsCiAicGljdHVyZSI6ICJodHRwOi8vZXhhbXBsZS5jb20vamFu
    ZWRvZS9tZS5qcGciCn0.
    NTibBYW_ZoNHGm4ZrWCqYA9oJaxr1AVrJCze6FEcac4t_EOQiJFbD2nVEPkUXPuM
    shKjjTn7ESLIFUnfHq8UKTGibIC8uqrBgQAcUQFMeWeg-PkLvDTHk43Dn4_aNrxh
    mWwMNQfkjqx3wd2Fvta9j8yG2Qn790Gwb5psGcmBhqMJUUnFrGpyxQDhFIzzodmP
    okM7tnUxBNj-JuES_4CE-BvZICH4jKLp0TMu-WQsVst0ss-vY2RPdU1MzL59mq_e
    Kk8Rv9XhxIr3WteA2ZlrgVyT0cwH3hlCnRUsLfHtIEb8k1Y_WaqKUu3DaKPxqRi6
    u0rN7RO2uZYPzC454xe-mg
    &state=af0ifjsldkj

id_token参数 的值是 ID Token,它是一个签名的 JWT,包含三个以句点(“.”)字符分隔的 base64url 编码的段。第一段代表 JOSE 标头。 Base64url 解码将产生以下一组标头参数:

  {"kid":"1e9gdk7","alg":"RS256"}

alg值表示用于签署 JWT 的算法,在本例中 为RS256 ,表示使用 SHA-256RSASSA-PKCS1-v1_5. Kid值是用于标识要用于验证签名的密钥的密钥标识符。如果RP不知道kid值,则需要再次检索OP的JWK集的内容以获得OP当前的密钥集。

第二段代表 ID 令牌中的声明。验证和解码 ID Token 将产生以下声明:

  {
   "iss": "https://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"
  }

第三段表示 ID Token 签名,其验证方式如[JWS] (Jones, M., Bradley, J., and N. Sakimura, “JSON Web Signature (JWS),” May 2015.)中所述。



目录

A.3.使用response_type=id_token token的示例

  GET /authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    access_token=jHkWEdUXMU1BwAsC4vtUsZwnNvTIxEl0z9K3vx5KF0Y
    &token_type=Bearer
    &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.
    ewogImlzcyI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAic3ViIjog
    IjI0ODI4OTc2MTAwMSIsCiAiYXVkIjogInM2QmhkUmtxdDMiLAogIm5vbmNlIjog
    Im4tMFM2X1d6QTJNaiIsCiAiZXhwIjogMTMxMTI4MTk3MCwKICJpYXQiOiAxMzEx
    MjgwOTcwLAogImF0X2hhc2giOiAiNzdRbVVQdGpQZnpXdEYyQW5wSzlSUSIKfQ.
    kdqTmftlaXg5WBYBr1wkxhkqCGZPc0k8vTiV5g2jj67jQ7XkrDamYx2bOkZLdZrp
    MPIzkdYB1nZI_G8vQGQuamRhJcEIt21kblGPZ-yhEhdkAiZIZLu38rChalDS2Mh0
    glE_rke5XXRhmqqoEFFdziFdnO3p61-7y51co84OEAZvARSINQaOWIzvioRfs4zw
    IFOaT33Vpxfqr8HDyh31zo9eBW2dSQuCa071z0ENWChWoPliK1JCo_Bk9eDg2uwo
    2ZwhsvHzj6TMQ0lYOTzufSlSmXIKfjlOsb3nftQeR697_hA-nMZyAdL8_NRfaC37
    XnAbW8WB9wCfECp7cuNuOg
    &state=af0ifjsldkj

验证和解码 ID Token 将产生以下声明:

  {
   "iss": "https://server.example.com",
   "sub": "248289761001",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "at_hash": "77QmUPtjPfzWtF2AnpK9RQ"
  }


目录

A.4.使用response_type=code id_token的示例

  GET /authorize?
    response_type=code%20id_token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk
    &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.
    ewogImlzcyI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAic3ViIjog
    IjI0ODI4OTc2MTAwMSIsCiAiYXVkIjogInM2QmhkUmtxdDMiLAogIm5vbmNlIjog
    Im4tMFM2X1d6QTJNaiIsCiAiZXhwIjogMTMxMTI4MTk3MCwKICJpYXQiOiAxMzEx
    MjgwOTcwLAogImNfaGFzaCI6ICJMRGt0S2RvUWFrM1BrMGNuWHhDbHRBIgp9.
    MRPihYtNIcwKTZ_mcMSPfreVytGR4jfl1Tzbv4tH5Jr4WqONs2lUWrIEpZ2joKbZ
    fAGlouAqwqSYpfR3FQYKYvdgnZ3kjIJ_5M4fAARXHVSciGyhfqB-OhDUMXSHzFHi
    GKNY9TKSgRfiXf_314WRujpqaDtj2uoXbppobYXvAZIxWtsOein0-t91LDS39EW4
    frNWAopKTBBi_XJPlpLVynWTDvNleEBP6UxIMgYJBKlqsP7RGfHTGk3ReXDacR7R
    GZlIVGa-0qRyDzvNqD7xfu9aYufUP0oBGqdBGgFVNmwJ7rmB0gdPtC2eJsXq9svC
    gBBfhRQZxhx1iLJjNc9nSw
    &state=af0ifjsldkj

验证和解码 ID Token 将产生以下声明:

  {
   "iss": "https://server.example.com",
   "sub": "248289761001",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "c_hash": "LDktKdoQak3Pk0cnXxCltA"
  }


目录

A.5.使用response_type=code token的示例

  {
   "iss": "https://server.example.com",
   "sub": "248289761001",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "c_hash": "LDktKdoQak3Pk0cnXxCltA"
  }


目录

A.6.使用response_type=code id_token token的示例

  GET /authorize?
    response_type=code%20id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &scope=openid%20profile%20email
    &nonce=n-0S6_WzA2Mj
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com

  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
    code=Qcb0Orv1zh30vL1MPRsbm-diHiMwcLyZvn1arpZv-Jxf_11jnpEX3Tgfvk
    &access_token=jHkWEdUXMU1BwAsC4vtUsZwnNvTIxEl0z9K3vx5KF0Y
    &token_type=Bearer
    &id_token=eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.
    ewogImlzcyI6ICJodHRwczovL3NlcnZlci5leGFtcGxlLmNvbSIsCiAic3ViIjog
    IjI0ODI4OTc2MTAwMSIsCiAiYXVkIjogInM2QmhkUmtxdDMiLAogIm5vbmNlIjog
    Im4tMFM2X1d6QTJNaiIsCiAiZXhwIjogMTMxMTI4MTk3MCwKICJpYXQiOiAxMzEx
    MjgwOTcwLAogImF0X2hhc2giOiAiNzdRbVVQdGpQZnpXdEYyQW5wSzlSUSIsCiAi
    Y19oYXNoIjogIkxEa3RLZG9RYWszUGswY25YeENsdEEiCn0.
    A2OhhJzbUNaCbNLqNaqetGLJoxB3ujVbq_HLYSOWgWCJ3-B__YxlqIg8gpeL0Vhv
    rWX0mwz7w_pGTRN4JdgsI0xAlT5fob1ZPnrazgonSyzaXcg2bgD896SsBSlG_8JX
    6JKaztXifn8k2gy65Me-sMyQrRF8xv_q1CeC871sZpMjJzy5nx65BTI17vcXjntZ
    HADv6o2CrHrEdHp8xSlnTLiiIqgDOmKlpkeqqOBK6dqa4rXZlSqMAUm1LYZmtb2D
    8sHvQsxTbWlBkX7VZaTSqMJ487s4ZIEea8Bw4KGVOntQue4VhBjBnQ4bQKhB_47D
    xlWpSyOWdy3cer_zxKrfvw
    &state=af0ifjsldkj

验证和解码 ID Token 将产生以下声明:

  {
   "iss": "https://server.example.com",
   "sub": "248289761001",
   "aud": "s6BhdRkqt3",
   "nonce": "n-0S6_WzA2Mj",
   "exp": 1311281970,
   "iat": 1311280970,
   "at_hash": "77QmUPtjPfzWtF2AnpK9RQ",
   "c_hash": "LDktKdoQak3Pk0cnXxCltA"
  }


目录

A.7.示例中使用的 RSA 密钥

以下以 JWK 格式表示的 RSA 公钥可用于验证上述示例中的 ID 令牌签名(值内换行仅用于显示目的):

  {
   "kty":"RSA",
   "kid":"1e9gdk7",
   "n":"w7Zdfmece8iaB0kiTY8pCtiBtzbptJmP28nSWwtdjRu0f2GFpajvWE4VhfJA
        jEsOcwYzay7XGN0b-X84BfC8hmCTOj2b2eHT7NsZegFPKRUQzJ9wW8ipn_aD
        JWMGDuB1XyqT1E7DYqjUCEOD1b4FLpy_xPn6oV_TYOfQ9fZdbE5HGxJUzeku
        GcOKqOQ8M7wfYHhHHLxGpQVgL0apWuP2gDDOdTtpuld4D2LK1MZK99s9gaSj
        RHE8JDb1Z4IGhEcEyzkxswVdPndUWzfvWBBWXWxtSUvQGBRkuy1BHOa4sP6F
        KjWEeeF7gm7UMs2Nm2QUgNZw6xvEDGaLk4KASdIxRQ",
   "e":"AQAB"
  }


目录

附录 B. 致谢

作为 OpenID 的后续版本,该规范在很大程度上依赖于OpenID Authentication 2.0 (OpenID Foundation, “OpenID Authentication 2.0,” December 2007.) [OpenID.2.0] 中探索的思想。请参阅 OpenID Authentication 2.0 的附录 C,了解该规范贡献者的完整列表。

此外,OpenID 社区还要感谢以下人员对此规范做出的贡献:

Naveen Agarwal (Naveen.Agarwal@microsoft.com),微软(曾在 Google)

阿曼达·安加内斯 (aanganes@mitre.org),MITRE

卡斯帕·比林 (cb@peercraft.com),Peercraft

John Bradley (ve7jtb@ve7jtb.com)、Yubico(曾在 Ping Identity)

Tim Bray (tbray@textuality.com),独立人士(曾在 Google)

Johnny Bufu (johnny.bufu@gmail.com),独立人士(曾在 Janrain)

Brian Campbell (bcampbell@pingidentity.com),Ping Identity

布莱恩·库克 (romeda@gmail.com),独立人士

布雷诺·德·梅代罗斯 (breno@google.com),Google

Pamela Dingle (Pamela.Dingle@microsoft.com),微软(曾在 Ping Identity)

Vladimir Dzhuvinov (vladimir@connect2id.com),Connect2id(曾在 Nimbus Directory Services)

George Fletcher (gffletch@aol.com),第一资本(曾在 AOL)

Roland Hedberg (roland@catalogix.se),独立人士(曾于于默奥大学)

伊藤亮 (ryo.ito@mixi.co.jp),mixi, Inc.

埃德蒙·杰伊 (ejay@mgi1.com),伊鲁米拉

Michael B. Jones (michael_b_jones@hotmail.com),自助咨询(曾在 Microsoft)

Torsten Lodderstedt (torsten@lodderstedt.net),独立人士(曾供职于德国电信)

詹姆斯·曼格 (James.H.Manger@team.telstra.com),澳大利亚电信

Nov Matake (nov@matake.jp),独立

Chuck Mortimore (charliemortimore@gmail.com),迪士尼(曾在 Salesforce)

Anthony Nadalin (nadalin@prodigy.net),独立人士(曾供职于 Microsoft)

Hideki Nara (hdknr@ic-tact.co.jp),Tact Communications

Axel Nennker (axel.nennker@telekom.de),德国电信

David Recordon (recordond@gmail.com),独立人士(曾供职于 Facebook)

Justin Richer (justin@bspk.io),定制工程(曾在 MITRE)

Nat Sakimura (nat@nat.consulting),NAT.Consulting(曾在 NRI)

卢克·谢泼德 (luke@lukeshepard.com),Facebook

Andreas Åkre Solberg (Andreas.Solberg@sikt.no),Sikt(曾在 UNINET)

保罗·塔里扬 (paul@paultarjan.com),Facebook



目录

附录 C. 通知

版权所有 (c) 2023 OpenID 基金会。

OpenID 基金会 (OIDF) 向任何贡献者、开发者、实施者或其他相关方授予非排他性、免版税、全球版权许可,以复制、分发、执行和展示本实施者草案或最终规范、准备衍生作品、分发、执行和展示仅用于 (i) 制定规范,以及 (ii) 根据此类文件实施实施者草案和最终规范,前提是注明材料来源为 OIDF,但此类来源并不表示认可由 OIDF 制定。

本规范中描述的技术来自各种来源的贡献,包括 OpenID 基金会的成员和其他人。尽管 OpenID 基金会已采取措施帮助确保该技术可供分发,但它对可能声称与实施或使用该技术相关的任何知识产权或其他权利的有效性或范围不持任何立场。本规范或此类权利下的任何许可可能或可能不可用的范围;它也不代表它已做出任何独立努力来确定任何此类权利。 OpenID 基金会和本规范的贡献者不做出(并特此明确否认任何)与本规范相关的保证(明示、暗示或其他方式),包括适销性、不侵权、特定用途的适用性或所有权的暗示保证。规范,并且实施该规范的全部风险由实施者承担。 OpenID 知识产权政策要求贡献者提供专利承诺,不会针对其他贡献者和实施者提出某些专利主张。 OpenID 基金会邀请任何感兴趣的各方提请其注意可能涵盖实践本规范所需的技术的任何版权、专利、专利申请或其他专有权利。



目录

作者地址

  纳特·萨基穆拉
  NAT咨询
电子邮件:  nat@nat.consulting
网址:  https://nat.sakimura.org/
  
  约翰·布拉德利
  尤比科
电子邮件:  ve7jtb@ve7jtb.com
网址:  http://www.thread-safe.com/
  
  迈克尔·琼斯
  自发行咨询
电子邮件:  michael_b_jones@hotmail.com
网址:  https://self-issued.info/
  
  布雷诺·德·梅代罗斯
  谷歌
电子邮件:  breno@google.com
网址:  https://stackoverflow.com/users/311376/breno
  
  查克·莫蒂摩尔
  迪士尼
电子邮件:  charliemortimore@gmail.com
网址:  https://twitter.com/cmort


英文原版