授权码授予方案

本方案分为两个阶段:用户授权阶段和获取令牌阶段。

用户授权阶段:

客户端引导资源所有者访问到授权页面地址,并等待资源所有者进行授权。

  1. 当资源所有者同意授权后,将携带一次性授权码请求客户端的回调地址;

  2. 当资源所有者拒绝授权后,将携带固定错误码请求客户端的回调地址;

  3. 如果资源所有者未进行授权相关操作,客户端将得不到任何回应。

如果成功得到一次性授权码, 则进入获取令牌阶段, 否则应按客户端自身业务作相应的处理。

获取令牌阶段:

当客户端得到资源所有者的一次性授权码后,凭此一次性授权码向授权服务器换取令牌。

换取的令牌至少包括访问令牌、令牌类型、剩余有效时间和权限条目,如果您的客户端支持刷新令牌授予方案,还将获得刷新令牌。

如果成功得到访问令牌,需要检查权限条目是否满足业务需要,令牌所携带的权限条目为资源所有者所选择。

时序图

sequenceDiagram autonumber participant C as 客户端 participant RO as 资源所有者 participant RS as 资源服务器 participant AS as 授权服务器 rect rgb(224, 192, 192) note over C,AS: 用户授权阶段 C->>+RO: 授权页面地址 RO->>+AS: 认证授权 AS-->>-RO: 授权码 RO-->>-C: 授权码 end rect rgb(192, 224, 192) note over C,AS: 获取令牌阶段 C->>+AS: 授权码 AS-->>-C: 令牌 end rect rgb(201, 202, 202) note over C,AS: 访问资源阶段 C->>+RS: 资源地址<br>(携带访问令牌) RS->>+AS: 访问令牌 AS-->>-RS: 资源所有者信息<br>和权限条目 RS-->>-C: 资源所有者相关的资源 end

* 图中访问资源阶段不在本章节进行讨论。

生成授权页面地址

本授权服务器同时接受显式(RFC 6749#section-4.1.1)和隐式(RFC 9126)两套授权页面地址方案。

如果客户端的require_pushed_authorization_requests元数据值设定为true,授权服务器将仅接受该客户端的隐式地址方案。

显式地址方案

警告

本方案中,所有参数均由资源所有者提交给授权服务器,存在资源所有者在访问到授权服务器之前读取、修改参数值的风险,客户端应当对此风险进行规避设计。

构成授权页面地址所需要的参数如下表:

授权请求参数

名称

类型

约束

描述

response_type

字符串

必选

固定值:code

client_id

字符串

必选

您的客户端标识。

redirect_uri

URL

条件

授权成功后的重定向地址。

如果客户端注册了多于一个重定向地址,此参数必须传入;
如果传入此参数,参数值必须与注册值完全相同。

scope

字符串

可选

请求权限条目。

如果有多个条目,使用空格符(ASCII:0x20," ")进行连接多个条目;
如果没有传入此参数,系统将按默认条目请求用户授权。

state

字符串

可选

附加信息。

如果传入此参数,当资源所有者成功授权后,访问重定向地址时将携带此参数值。

本参数设计是用于防范跨站请求伪造(参考资料:MDN),建议您进行传入。
* 如果客户端需要将业务与授权请求进行关联,也可以将相应的映射字符串作为参数值进行传入。

code_challenge

字符串

条件

挑战码。由验证码经过演算法所得:
plain,此值为验证码原始值;
S256SM3,此值为经过使用URL安全字母表进行BASE64编码(RFC 4648#section-5)的杂凑演算值。

如果客户端类型为公开客户端,此参数必须传入。
本参数设计是用于防范授权码被攻击者拦截进而窃取到令牌(参考资料:RFC 7636#section-1),建议您进行传入。

code_challenge_method

字符串

可选

挑战码演算法。默认值为plain,即不进行演算。

本授权服务器支持:
plain——不进行演算;
S256——使用SHA-256安全杂凑演算法进行演算;
SM3——使用SM3密码杂凑算法进行演算。

将参数通过application/x-www-form-urlencoded编码后,作为URL查询参数附加到授权服务器授权地址,得到的目标URL即为资源所有者进行授权操作的入口地址。

地址示例(带有额外的换行符,仅用于显示目的)

https://oauth2.api.neusoft.edu.cn/authorize?
client_id=dummy
&redirect_uri=https%3A%2F%2Fclient.example.net%2Foauth2%2Fcallback
&response_type=code
&scope=core%3Auser%3Aid
&state=dummy
&code_challenge=IHz0EFMvkqR97iRc6bEf9x9Xjr12PrO76kTr0EPQGPs
&code_challenge_method=SM3

隐式地址方案

备注

本方案中,所有参数先由客户端提交给授权服务器,需要消耗一定的执行时间,客户端应当在交互界面中进行视觉设计。

与显式地址方案不同的是,客户端先将参数通过预推送授权请求接口提交到授权服务器得到一个请求URI,再将得到的请求URI作为URL查询参数附加到授权服务器授权地址,目标URL即为资源所有者进行授权操作的入口地址。

地址示例(带有额外的换行符,仅用于显示目的)

https://oauth2.api.neusoft.edu.cn/authorize?
client_id=dummy
&request_uri=urn%3Aietf%3Aparams%3Aoauth%3Arequest_uri%3A8bda7bd6-37a4-4eb9-9d81-62da8912e31e

接受资源所有者回调

如果资源所有者成功在授权服务器进行授权,将会回调到该请求所对应的客户端回调地址,并携带如下参数:

名称

类型

约束

描述

code

字符串

必选

一次性授权码。

state

字符串

条件

附加信息。

如果在生成授权页面地址时传入此参数,此参数原样返回。

iss

URL

必选

授权服务器根地址,当前值:https://oauth2.api.neusoft.edu.cn

回调请求示例(带有额外的换行符,仅用于显示目的)

https://client.example.net/oauth2/callback?
code=b19c69b1-86da-4f26-ab31-0560d0740c2d
&state=dummy
&iss=https%3A%2F%2Foauth2.api.neusoft.edu.cn

客户端在接收到回调请求时,应当:

  1. 检查iss值是否为本授权服务器当前值;

  2. 检查state值是否与预留值相同;

  3. 使用一次性授权码从授权服务器获取令牌。

获取令牌

客户端从回调请求中获取到一次性授权码后,可通过授权码授予令牌请求接口获取相应令牌。如果在生成授权页面地址阶段传入了挑战字参数,此时也要一同传入。

获取成功后,应当检查令牌携带权限列表是否满足使用需要。如果满足,应当将访问令牌进行暂存,并注意剩余有效时间。

如果有刷新令牌,应进行持久化存储,目前刷新令牌的有效时间为自授权时起一年(365天,31536000秒)。