-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[proposal] Yggdrasil Connect Specification (Public Review) #268
Comments
LTCatt comment at Hex-Dragon/PCL2#5132 (comment)
|
启动器作者是否实现、如何实现 Yggdrasil Connect 是其个人自由。 |
在我看来应用注册部分只需要规定一个公共应用就够了。主动注册不关规范的事情,应该让启动器和皮肤站之间自行解决;动态注册过于复杂,在有共用应用的情况下应该没什么人会愿意实现。 总之这只是个草案,我觉得其中很多部分还可以考虑进一步简化,篇幅也可以压缩。 |
Thank you for creating this proposal. If OAuth 2.0 login is going to be adopted by launchers and authentication servers, then I believe it should be standardized by authlib-injector.
In my opinion, requiring OIDC identity providers to "approve" each Relying Party by issuing them a client ID and client secret is one of the worst design decisions of OAuth2.0/OIDC and has been a disaster for interoperability. I don't want a future where every launcher developer has to get permission from every authentication server. OIDC Dynamic Client Registration (https://openid.net/specs/openid-connect-registration-1_0.html) seems like the "correct" way to solve this problem. Having a single public client ID for all launchers/other relying parties might work too... but how would the
I agree, this repeats much of what is already defined by OIDC. The important details are how Yggdrasil Connect will extend OIDC (the left side of the Venn diagram at the top) rather than OIDC itself. |
That's the difference between YggC and OIDC. In my opinion (and the PR spec), shared client ("single public client ID") could accept any redirect_uri with For launchers, you could just use RFC 8628 OAuth 2.0 Device Authorization Grant (Device Code Flow). That's the most used way to authenticate with Microsoft on Chinese Minecraft launchers, and it doesn't require redirect_uri. |
Yggdrasil Connect 是基于 OpenID Connect 协议的全新用户身份认证协议,为 authlib-injector 外置登录提供了一种基于 OAuth 2.0 的用户身份认证解决方案,目的是取代 Yggdrasil API 中的 Auth Server 部分。
以下是 Yggdrasil Connect 协议的规范文档的草案,供公开审阅:
下载 PDF 版本
概述
Yggdrasil Connect 是基于 OpenID Connect 协议的全新用户身份认证协议,其目的是取代 Yggdrasil API 中的 Auth Server 部分。
在 Yggdrasil API 的 Auth Server 部分中,用户需要将自己的用户名和密码直接暴露给第三方应用,才能通过第三方应用访问 Yggdrasil API,这增加了用户账户关键信息泄露的风险;且该部分的 API 在设计上几乎没有考虑到二步验证,无法良好地保障用户账户的安全。并且,由于各个第三方应用在该部分的实现的差异,用户在不同应用之间的登录体验存在较大割裂,时常出现应用实现不完整导致用户无法正常登录的问题。
Yggdrasil Connect 的目的即是解决这些问题。通过 OpenID Connect 协议,Yggdrasil Connect 可以实现用户在不同应用间的登录体验的统一,同时方便各验证服务器自行设计用户身份认证方式,以保障用户账户的安全。
OAuth 2.0、OpenID Connect 及 Yggdrasil Connect 的关系
Yggdrasil Connect 协议基于 OpenID Connect 协议及其扩展 MS-OIDCE,而 OpenID Connect 基于 OAuth 2.0 协议。
本质上,Yggdrasil Connect 仅是针对 Minecraft 多人联机玩家身份认证场景,对 OpenID Connect 协议进行了部分简化及少量扩展。通过利用 OpenID Connect 协议中的 ID 令牌、服务发现等特性,并在此之上定义统一的权限范围及用户信息声明,第三方应用(如启动器)可以从不同的 Yggdrasil 验证服务器处向用户请求 OAuth 2.0 授权并获取访问令牌,以实现 authlib-injector 外置登录,而无需针对不同的验证服务器编写针对性的代码。
由于 OpenID Connect 协议基于 OAuth 2.0 协议,因此所有的 OpenID 提供者(OpenID Provider,OP,即所谓的“OpenID Connect 认证服务器”)同时也应为 OAuth 2.0 授权服务器(Authorization Server,AS);但反之不成立,即不是所有的 OAuth 2.0 授权服务器都是 OpenID 提供者。
由于 Yggdrasil Connect 协议对 OpenID Connect 协议进行了部分简化,因此不是所有的 Yggdrasil Connect 验证服务器都是 OpenID 提供者;反之亦然,由于 Yggdrasil Connect 协议对 OpenID Connect 协议进行了扩展,因此不是所有的 OpenID 提供者都是 Yggdrasil Connect 服务器。但 Yggdrasil Connect 协议对 OAuth 2.0 授权服务器的实现相对完整,因此可以说所有 Yggdrasil Connect 验证服务器都是 OAuth 2.0 授权服务器,但反之不成立,即不是所有的 OAuth 2.0 授权服务器都是 Yggdrasil Connect 验证服务器。
综上所述,在 Yggdrasil Connect 应用开发中,开发者或许无法直接使用现成的 OpenID Connect 客户端库(可以尝试使用,但不保证一定可用),但可使用现成的 OAuth 2.0 客户端库,并在其基础上进行扩展以实现 Yggdrasil Connect 客户端。考虑到 OAuth 2.0 及 OpenID Connect 客户端的最小实现也较为简单,从零开始实现 Yggdrasil Connect 客户端也并不复杂。同理,在 Yggdrasil Connect 验证服务器开发中,开发者可尝试直接使用现成的 OAuth 2.0 或 OpenID Connect 服务端库,并在其基础上进行扩展以实现 Yggdrasil Connect 验证服务器。
由于 Yggdrasil Connect 协议本身基于 OpenID Connect 协议,因此 Yggdrasil Connect 不止可以为 authlib-injector 外置登录的验证服务器所用。通过构建合理的 OAuth 2.0 授权服务器和鉴权体系,Yggdrasil Connect 验证服务器的适用范围和应用场景可以扩展至 authlib-injector 外置登录之外。
参考文档
基本约定
模型
验证服务器
验证服务器是 Yggdrasil Connect 的核心部分,它负责处理用户身份认证请求,并返回用户身份认证结果。
验证服务器分为两个逻辑服务器:
两个逻辑服务器可以是同一个单体服务,也可以是使用不同域名的、分离的服务。
验证服务器必须以 HTTPS 协议提供服务,所有 URL 均必须以
https://
开头。客户端应拒绝使用不支持 HTTPS 协议的验证服务器,也不得在任何情况下降级为 HTTP 协议。本文档主要描述认证服务器的实现规范。考虑到用户身份认证主要由启动器在 Minecraft 游戏外处理,所以在认证服务器部分使用与 Mojang 官方不同的实现并无不妥;但会话服务器需要与 Minecraft 游戏本体进行交互,其行为应能被 Minecraft 游戏本体正确处理,而具体规范已于 Yggdrasil 服务端技术规范 中记载(会话部分、角色部分),本文档不再重复说明。
认证服务器至少具有以下属性:
kid
字段)。认证服务器需要实现以下 API 端点:
上述 API 端点的 URL 可由验证服务器自定义,但必须标注于认证服务器的 OpenID 提供者元数据中。详见 OpenID 提供者元数据。
用户
一个验证服务器中可以存在多个用户。
用户必须具有的属性只有一个:
除此之外,Yggdrasil Connect 还建议用户包含以下属性:
用户注册和登录的方式,以及所需的凭证(如密码)等信息,应由验证服务器自行设计。
角色
角色(或称为档案,Profile)对应着 Minecraft 游戏中的玩家实体。
角色与用户为多对一关系,即一个用户可以拥有多个角色。
角色具有以下属性:
角色信息的序列化
参见 Yggdrasil 服务端技术规范 § 角色信息的序列化。
多角色场景下的角色选择
部分验证服务器可能支持单个用户持有多个角色。在该场景下,出于用户隐私和应用适配难度考虑,认证服务器应支持在授权时选择角色。
如应用在请求授权时申请了
Yggdrasil.PlayerProfiles.Select
权限范围,则认证服务器应在询问用户授权时要求用户选择角色,详见 权限范围;用户完成角色选择并授权后,如认证服务器最终向应用颁发访问令牌,则该访问令牌必须绑定至角色,详见 访问令牌。应用
应用是需要访问 Yggdrasil API 的主体,在 OpenID Connect 协议中被称为依赖方(Relying Party, RP)。
应用具有以下属性:
除此之外,Yggdrasil Connect 还建议应用包含以下可选属性:
应用、客户端和 Minecraft 本体的关系
应用是一个逻辑概念,是客户端在认证服务器上的抽象表示,而客户端是应用的具体实现,是用户直接与之交互的实体。
应用与客户端是一对多的关系,多个客户端可以使用同一应用标识符来请求访问权限。认证服务器不需要了解应用拥有多少个客户端,只需要按照规范规定对客户端进行鉴权即可。如需撤销访问权限或对应用实施限制措施,则相关操作应直接作用于整个应用。
Note
以 HMCL 为例:
HMCL 是一个应用,它在认证服务器上有一个抽象的表示。
HMCL 3.5 和 HMCL 3.6 是 HMCL 应用的两个不同的客户端,这两个客户端使用相同的应用标识符来请求访问权限。
如果用户撤销了对 HMCL 的授权,实际上是撤销了对整个 HMCL 应用的授权。因此,无论是哪个版本的 HMCL 启动器,都将失去访问受保护资源的权限,直到用户重新授权。
通常情况下,Minecraft 本体并不直接与认证服务器交互,因此其既不是应用,也不是客户端。然而,在与会话服务器交互时,Minecraft 本体会使用启动器在启动游戏时传入的访问令牌进行鉴权(换句话说,其以应用的身份与会话服务器交互),因此其应被视为持有该访问令牌的应用的一个客户端。
机密客户端和公共客户端
客户端根据其安全特性和能力,可以分为两类:
Note
认证服务器可通过应用请求授权时使用的授权流来区分客户端类型:
为降低公共客户端的安全问题带来的影响,认证服务器应对公共客户端加以限制,例如:
prompt=consent
)。具体限制措施应由认证服务器自行设计和实施。
令牌
Yggdrasil Connect 中存在三种令牌:
访问令牌
访问令牌是应用代表用户访问受保护的资源及执行操作(如获取用户信息及加入多人游戏服务器)时使用的凭证。访问令牌由认证服务器在用户授予应用访问权限后向应用颁发,其值可为任意 ASCII 字符串。
访问令牌具有时效性,在有效期内可多次使用;访问令牌过期后,应用如需继续访问受保护的资源或执行操作,则需要获取一个新的访问令牌。访问令牌与刷新令牌为一对一关系,访问令牌被吊销后,其对应的刷新令牌也应被吊销。
对应用来说,访问令牌是不透明的。这意味着访问令牌没有明确的模型定义,只需要验证服务器可以通过访问令牌来确定用户和应用的身份及其权限范围即可。
单个应用可以持有同一用户的多个访问令牌,但验证服务器应对同一应用持有的属于单一用户的有效的访问令牌的数量进行限制。当访问令牌数量超出限制时,应先吊销颁发时间最早的有效的访问令牌,然后再颁发新的访问令牌。
在 Yggdrasil Connect 中,访问令牌不再必须绑定至角色,但若访问令牌已绑定至角色,则仅应允许对已绑定的角色执行操作。
访问令牌的使用
除会话服务器外,Yggdrasil Connect 中访问令牌的使用方法与 OAuth 2.0 协议一致,即,将访问令牌作为 Bearer Token,在请求受保护的 API 时放置于 HTTP 请求的
Authorization
头部中:如访问令牌有效,且请求无误,API 将返回正常响应;如访问令牌无效或请求参数有误,API 将根据错误类型返回对应的 HTTP 状态码,并在 HTTP 响应的
WWW-Authenticate
头部中返提供详细错误信息。关于错误响应的更多信息,详见 错误响应。
Note
关于在会话服务器中使用访问令牌以实现 authlib-injector 外置登录的方法,请参阅 Yggdrasil 服务端技术规范 - 会话部分。
访问令牌有效性的验证
如应用需要验证访问令牌的有效性,可使用访问令牌请求用户信息端点:
invalid_token
错误,则说明访问令牌无效。详见 用户信息端点 和 错误响应。
刷新令牌
刷新令牌是一种特殊的令牌,用于在访问令牌有效期内及过期后一段时间内刷新访问令牌(即,吊销刷新令牌对应的访问令牌,并颁发一个新的访问令牌及对应的刷新令牌)。详见 令牌的刷新。
刷新令牌也具有时效性,其有效期可以比其对应的访问令牌稍长,但刷新令牌仅能使用一次。刷新令牌与访问令牌为一对一关系,访问令牌被吊销后,其对应的刷新令牌也应被吊销。
与访问令牌相同,刷新令牌对应用来说也是不透明的,因此刷新令牌也没有明确的模型定义,只需要验证服务器可以通过刷新令牌来确定对应的访问令牌即可。
刷新令牌随着访问令牌一同颁发,但应仅在授权时申请了
offline_access
权限范围时颁发。详见 权限范围。ID 令牌
ID 令牌是 OpenID Connect 对 OAuth 2.0 进行的最主要的扩展,它是一个由认证服务器签名的、包含了用户身份信息声明的 JWT。不同于访问令牌和刷新令牌,ID 令牌并非用于鉴权,而是提供给应用做用户身份进行验证及用户信息获取之用。
ID 令牌也具有时效性,其有效期一般与访问令牌一致。已过期的 ID 令牌是不可信的,不得被再次使用。
ID 令牌随着访问令牌一同颁发,但应仅在授权时申请了
openid
权限范围时颁发。详见 权限范围。ID 令牌具有以下声明和属性:
iss
sub
aud
iat
exp
selectedProfile
Yggdrasil.PlayerProfiles.Select
权限范围,则必须具有。包含用户选择的访问令牌绑定的角色的信息的 JSON 对象(不包含角色属性)。参见 角色信息的序列化。availableProfiles
Yggdrasil.PlayerProfiles.Read
权限范围,则必须具有。包含用户名下所有可用角色的角色信息的 JSON 对象的JSON 数组(不包含角色属性)。参见 角色信息的序列化。除上述声明外,根据应用所申请的权限范围,ID 令牌中还可包含更多可选字段,以及其它由认证服务器自定义的声明。应用必须忽略 ID 令牌中的无法识别的声明。
OpenID Connect 还规定了更多可选声明,篇幅所限,在此不再赘述。如需了解,请参阅 OpenID Connect Core 1.0 规范的第 5.1 节。
以下是一个使用 RS256 算法签名的 ID 令牌的示例:
对该 ID 令牌进行解析,得到其 JWT 头部和负载分别为:
ID 令牌的签名
ID 令牌必须由认证服务器使用其拥有的签名密钥对签名,且所使用的签名算法及密钥 ID 必须分别标注于 ID 令牌的 JWT 头部的
alg
字段和kid
字段中。允许使用的签名算法如下:
RS256
、RS384
、RS512
ES256
、ES384
、ES512
、ES256K
EdDSA
除非应用在注册时明确声明其支持其它签名算法,否则认证服务器应默认使用 RS256 算法对 ID 令牌进行签名。
ID 令牌有效性的验证
应用在使用 ID 令牌前,应按照以下规则对 ID 令牌进行验证:
iss
声明的值与 OpenID 提供者标识符一致。aud
声明的值与应用标识符一致。如 ID 令牌不满足上述条件中的任意一条,其应被视为无效令牌。应用必须拒绝使用无效的 ID 令牌。
应用可通过认证服务器的 OpenID 提供者元数据中
jwks_uri
字段的值来获得用于验证 ID 令牌的签名的密钥的集合(JWKS 格式)。详见 OpenID 提供者元数据。权限范围
在 OAuth 2.0 中,权限范围(scope)用于限定持有访问令牌的应用允许访问的资源的范围。
Yggdrasil Connect 规定了如下权限范围:
openid
profile
offline_access
Yggdrasil.PlayerProfiles.Select
selectedProfile
声明中。Yggdrasil.PlayerProfiles.Read
availableProfiles
声明中。Yggdrasil.Server.Join
Yggdrasil.PlayerProfiles.Select
权限范围(换句话说,访问令牌必须绑定至角色);如未申请该权限范围,则会话服务器必须拒绝使用该访问令牌的客户端进入;如未申请该权限范围,则会话服务器必须拒绝使用该访问令牌的客户端进入 Minecraft 多人游戏服务器。Warning
如应用在请求授权时申请了上述任一权限范围,但未同时申请
openid
权限范围,认证服务器应拒绝授权,并返回invalid_scope
错误。Important
为防止用户被误导,认证服务器不应允许应用同时申请
Yggdrasil.PlayerProfiles.Select
和Yggdrasil.PlayerProfiles.Read
权限范围。OpenID Connect 还规定了更多可选的权限范围,篇幅所限,在此不再赘述。如需了解,请参阅 OpenID Connect Core 1.0 规范。
错误响应
除会话服务器外,Yggdrasil Connect 中的错误响应与 OAuth 2.0 协议即 OpenID Connect 协议一致。
认证服务器可能通过多种方式返回错误(如,在应用回调 URL 的查询参数中返回错误、在 HTTP 响应体中返回错误等),但所有错误响应都包含下列参数:
error
error_description
error_uri
错误响应的形式
认证服务器可以以下形式返回错误:
在应用回调 URL 的查询参数中返回错误
在应用的回调 URL 的查询参数中添加错误响应参数的错误响应形式。
仅于 OAuth 2.0 授权代码流或隐式流的授权响应中返回,因为授权代码流和隐式流的授权响应即是 URL 回调。
详见 RFC 6749 的 4.1.2.1 节和 4.2.2.1 节。
在 HTTP 响应体中返回错误
在 HTTP 响应体中返回一个包含错误响应参数的 JSON 文档的错误响应形式。
于 OAuth 2.0 令牌响应及设备代码流的授权响应中返回。
详见 RFC 6749 的 5.2 节。
在 HTTP 响应头中返回错误
在 HTTP 响应的
WWW-Authenticate
头部中添加错误响应参数的错误响应形式。于应用使用访问令牌获取受 OAuth 2.0 保护的资源或执行操作时返回。
其中
realm
为一个可选的参数,其值为访问该 API 端点所需的权限范围。详见 RFC 6750 的第三章。
错误类型
下列是部分 OAuth 2.0 和 OpenID Connect 协议中常见的错误类型:
access_denied
401 Unauthorized
。authorization_pending
400 Bad Request
。expired_token
400 Bad Request
。insufficient_scope
403 Forbidden
。invalid_client
401 Unauthorized
。invalid_request
400 Bad Request
。invalid_scope
400 Bad Request
。invalid_token
401 Unauthorized
。server_error
500 Internal Server Error
。slow_down
authorization_pending
错误的变种,正在等待用户完成授权,但应用轮询过快。400 Bad Request
。temporarily_unavailable
503 Service Unavailable
。OAuth 2.0 及 OpenID Connect 还规定了更多错误类型,详见 RFC 6749、RFC 8628 及 OpenID Connect Core 1.0 规范。
服务发现
Yggdrasil Connect 的服务发现依赖于 authlib-injector API 元数据获取 。
支持 Yggdrasil Connect 的验证服务器的 authlib-injector API 元数据中应包含一个
feature.openid_configuration_url
字段,其值为该验证服务器的 OpenID 提供者的元数据的 URL。若验证服务器的 authlib-injector API 元数据中不包含该字段,则应认为该验证服务器不支持 Yggdrasil Connect。Note
OpenID 提供者可以使用与 Yggdrasil API 不同的域名,只需要保证会话服务器能够识别并验证 OpenID 提供者颁发的访问令牌即可。
OpenID 提供者元数据
OpenID 提供者元数据是一个 JSON 文档,其中标明了 OpenID 提供者支持的各项参数,是 Yggdrasil Connect 服务发现的重要组成部分。
OpenID 提供者元数据应位于 OpenID 提供者标识符 URL 下的
/.well-known/openid-configuration
中,可由客户端在无需鉴权的情况下通过发起 GET 请求获取:Yggdrasil Connect 规定 OpenID 提供者元数据中应包含下列字段:
issuer
authorization_endpoint
device_authorization_endpoint
token_endpoint
userinfo_endpoint
registration_endpoint
jwks_uri
scopes_supported
openid
、Yggdrasil.PlayerProfiles.Select
和Yggdrasil.Server.Join
三项权限范围,如不包含其中任意一项,则应视为该 OpenID 提供者不支持 Yggdrasil Connect。subject_types_supported
public
:针对单一用户,向所有应用返回相同的用户标识符。pairwise
:针对同一用户,向不同的应用返回不同的用户标识符。id_token_signing_alg_values_supported
RS256
。shared_client_id
上述字段中,
authorization_endpoint
和device_authorization_endpoint
必须提供其中至少一个。OpenID Connect 还规定了更多可选字段,篇幅所限,在此不再赘述。如需了解,请参阅 OpenID Connect Discovery 1.0 规范的第三章。
以下是一个 OpenID 提供者元数据的示例:
应用注册
应用必须事先在认证服务器上注册,并获取应用标识符,然后才能请求用户授权。
Yggdrasil Connect 支持的应用注册方式有三种:
认证服务器应至少支持上述三种应用注册方式中的一种。
主动注册
最主流的应用注册方式,由应用开发者通过认证服务器提供的用户界面手动注册应用。
具体实现方式可由认证服务器自行设计。
动态注册
由客户端以编程方式通过 OpenID Connect 动态客户端注册(Dynamic Client Registeration)自动注册应用。
由于其规范较为复杂,在此暂不详细描述,具体请参见 OpenID Connect Dynamic Client Registeration 1.0 规范。
公用应用
由认证服务器预先注册一个应用,将其应用标识符标注于 OpenID 提供者元数据的
shared_client_id
中,客户端直接以该应用的身份请求授权。Note
公用应用的应用机密不应该对外公开。因此,所有以公用应用身份请求授权的客户端均应被视为公共客户端。详见 机密客户端和公共客户端。
由于公用应用不支持配置回调 URL,因此其回调 URL 可以为本地环回地址或任意以
https://
开头的 URL。认证服务器应对公用应用实施一定的限制措施,例如:
prompt=consent
)。具体限制措施应由认证服务器自行设计。
授权流程
本章以 Minecraft 启动器中最常见的两种 OAuth 2.0 授权流(授权代码流、设备代码流)为例,描述应用请求授权的流程。
授权代码流
RFC 6749 的 4.1 节中描述的 OAuth 2.0 授权方式。
请求用户授权
请求
首先,应用需要在认证服务器的授权端点 URL 之上拼接以下查询参数,形成授权 URL:
client_id
redirect_uri
response_type
code
。关于其它授权流的取值,请参阅 RFC 6749。scope
state
OAuth 2.0 及 OpenID Connect 还规定了更多参数,详见 RFC 6749 及 OpenID Connect Core 1.0 规范。
以下是一个拼接好参数的授权 URL 的示例:
然后,应用需要将用户重定向至授权 URL。认证服务器此时需要提供一个用户界面,向用户展示应用信息及其申请的权限,并让用户决定是否授权。
响应
用户完成授权后,认证服务器需要将用户重定向至应用提供的回调 URL,并在查询参数中添加授权响应:
code
state
state
参数,则必须具有。其值必须与应用在该次授权请求中提供的state
参数值一致。以下是一个回调示例:
应用需要校验授权响应中的
state
的值是否与授权请求中的一致,并暂存授权代码,以备之后请求颁发访问令牌。Tip
如授权过程中发生错误,认证服务器也需要将用户重定向至应用提供的回调 URL,并在查询参数中添加错误响应参数。详见 在应用回调 URL 的查询参数中返回错误 以及 错误类型。
获取访问令牌
请求
获取到授权代码后,应用需要在后端向认证服务器的令牌端点发送 POST 请求,并在请求体中携带以下表单参数(Content-Type 为
application/x-www-form-urlencoded
),以请求颁发访问令牌:grant_type
authorization_code
。client_id
client_secret
redirect_uri
code
以下是一个请求示例:
响应
如请求有误,认证服务器应在响应体中返回错误,详见 在 HTTP 响应体中返回错误 以及 错误类型。
如请求无误,认证服务器应返回 JSON 响应,并在其中包含下列参数,以向应用颁发令牌:
token_type
Bearer
。expires_in
access_token
refresh_token
offline_access
权限范围,则必须提供。id_token
openid
权限范围,则必须提供。以下是一个响应示例:
设备代码流
RFC 8628 中描述的 OAuth 2.0 授权方式。
请求用户授权
请求
首先,应用需要向认证服务器的设备授权端点发送 POST 请求,并在请求体中携带以下表单参数(Content-Type 为
application/x-www-form-urlencoded
),以获取设备代码和用户代码:client_id
scope
以下是一个请求示例:
响应
如请求无误,认证服务器应返回 JSON 响应(Content-Type 为
application/json
),并在其中包含下列参数:device_code
user_code
verification_uri
verification_uri_complete
expires_in
interval
以下是一个响应示例:
如请求有误,认证服务器应在 HTTP 响应体中返回错误,详见 在 HTTP 响应体中返回错误。
获取到设备代码和用户代码后,应用应引导用户访问授权页面,并按页面提示操作。
认证服务器应让用户在授权页面中输入用户代码,以识别授权请求,然后向用户展示应用信息及其申请的权限,并让用户决定是否授权。
获取授权结果和访问令牌
请求
获取到设备代码后,应用需要在后台以
interval
为间隔,向认证服务器的令牌端点发送 POST 请求,并在请求体中携带以下表单参数(Content-Type 为application/x-www-form-urlencoded
),以查询授权结果:grant_type
urn:ietf:params:oauth:grant-type:device_code
client_id
device_code
以下是一个请求示例:
响应
如请求有误,或用户还未完成授权,认证服务器应在响应体中返回错误:
authorization_pending
错误。access_denied
错误。expired_token
错误。详见 在 HTTP 响应体中返回错误 以及 错误类型。
如请求无误,且用户已完成授权,则认证服务器应返回 JSON 响应,并在其中包含下列参数,以向应用颁发令牌:
token_type
Bearer
。expires_in
access_token
refresh_token
offline_access
权限范围,则必须提供。id_token
openid
权限范围,则必须提供。以下是一个响应示例:
令牌的刷新
为了延长单次授权的有效期,可在访问令牌有效期及过期后一段时间内使用刷新令牌请求刷新访问令牌,以获取一个新的访问令牌。
请求
应用需要向认证服务器的令牌端点发送 POST 请求,并在请求体中携带以下表单参数(Content-Type 为
application/x-www-form-urlencoded
):grant_type
refresh_token
client_id
client_secret
refresh_token
以下是一个请求示例:
响应
如请求有误,认证服务器应在响应体中返回错误,详见 在 HTTP 响应体中返回错误 以及 错误类型。
如请求无误,认证服务器应返回 JSON 响应,并在其中包含下列参数,以向应用颁发令牌:
token_type
Bearer
。expires_in
access_token
refresh_token
offline_access
权限范围,则必须提供。id_token
openid
权限范围,则必须提供。以下是一个响应示例:
用户信息的获取
使用 ID 令牌
ID 令牌中已包含部分用户信息,直接对 ID 令牌进行 JWT 解码即可获得用户信息。
除必须具有的声明外,根据应用申请的权限范围的不同,ID 令牌中可能还包含更多可选声明,以及其它认证服务器自定义的声明。
Note
应用必须忽略 ID 令牌中其无法识别的声明。详见 ID 令牌。
在从 ID 令牌中获取用户信息之前,应用必须先验证 ID 令牌的有效性。无效的 ID 令牌是不可信的,因此不应从无效的 ID 令牌中获取用户信息。详见 ID 令牌有效性的验证。
用户信息端点
用户信息端点是一个受 OAuth 2.0 保护的 API 端点,用于向应用提供用户信息。其返回的信息是 ID 令牌中的声明的超集,但不包含
iss
声明、iat
声明和exp
声明。应用可以通过认证服务器的 OpenID 提供者元数据中的
userinfo_endpoint
字段的值来获取认证服务器的用户信息端点的 URL,按 OAuth 2.0 规范向其发送 GET 请求即可获取当前授权令牌所属的用户信息:以下是一个用户信息端点响应的示例:
除必须具有的声明外,根据应用申请的权限范围的不同,用户信息端点的响应中可能还包含更多可选声明,以及认证服务器自定义的其它声明。
Note
应用必须忽略用户信息端点的响应中的无法识别的声明。详见 ID 令牌。
Important
出于用户隐私安全考虑,认证服务器可以选择不向应用提供其请求的部分声明。
如认证服务器决定不向应用提供某些声明,必须直接在用户信息端点的响应中省略对应的声明,而不是将声明值设为空值或
null
。除认证服务器未提供必须具有的声明的情况外,应用不应将“认证服务器未提供应用所请求的声明”视为错误。
The text was updated successfully, but these errors were encountered: