IdentityServer4是基于OpenID Connect and OAuth 2.0框架,OpenID Connect Core 1.0是IdentityServer4最重要的文档
3.1.2.6 验证错误响应(Authentication Error Response)
验证错误响应是一个OAuth 2.0授权错误响应消息,是RP发送授权请求的消息,由OP授权终结点的响应返回。
如果终端用户拒绝这个请求或终端用户验证失败,OP(授权服务器) 通过使用错误响应通知RP(客户端),其参数定义在 OAuth 2.0 [RFC6749] 4.1.2.1节中。与RFC 6749(HTTP错误返回给User Agent使用适当的HTTP状态码。)
除非重定向的URI无效,授权服务器返回的由客户端重定向的URI中指定的授权请求与适当的错误和状态参数。其他参数不应该返回。
除了 OAuth 2.0 4.1.2.1节定义的错误代码,该规范还定义了以下错误代码:
interaction_required
授权服务器需要某种形式与终端用户进行交互。当在认证请求中包含prompt参数值为none时,这个错误可能会返回,但在没有显示终端用户操作的用户界面减肥,验证请求不能完成。
login_required
授权服务器需要终端用户进行验证。当在认证请求中包含prompt参数值为none时,这个错误可能会返回,但在没有显示终端用户操作的用户界面减肥,验证请求不能完成。
account_selection_required
对终端用户是必需的,当选择一个会话在授权服务器。当终端用户没有选择会话,但终端用户又可能在授权认证服务器与不同账户关。当在认证请求中包含prompt参数值为none时,这个错误可能会返回,但在没有显示终端用户操作的用户界面减肥,验证请求不能完成。
consent_required
授权服务器需要终端用户同意。当在认证请求中包含prompt参数值为none时,这个错误可能会返回,但在没有显示终端用户操作的用户界面减肥,验证请求不能完成。
invalid_request_uri
授权请求返回的request_uri中返回包含一个错误或包含无效数据。
invalid_request_object
request参数包含一个无效的请求对象。
request_not_supported
OP不支持使用在第六节中定义的request参数。
request_uri_not_supported
OP不支持使用在第六节中定义的request_uri 参数。
registration_not_supported
OP不支持使用在7.2.1节中定义的 registration 参数 。
错误响应参数如下:
error
必需的。错误代码。
error_description
可选的。人类可读的ASCII 编码的文本描述的错误。
error_uri
可选的。包括额外的信息错误web页面的URI。
state
OAuth 2.0状态值。如果需要包括 state 参数授权请求。设置从客户端收到的值。
当使用授权码流,添加到重定向查询组件的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验证响应验证(Authentication Response Validation)
当使用授权码流,客户端必须根据RFC 6749验证响应,尤其是4.1.2和10.12节。
3.1.3令牌终结点(Token Endpoint)
获得Access Token,ID Token,和可选的Refresh Token,RP(客户端)发送一个令牌请求给令牌终结点并获得令牌的响应。使用授权码流,如3.2节的 OAuth 2.0 (RFC6749) 所述。
与令牌通信终结点必须使用TLS。参看 16.17节 使用TLS的更多信息。
3.1.3.1令牌的请求(Token Request)
客户端发出一个令牌请求,出示其授权许可(授权码一种形式),为令牌终结点提供grant_type 值,就像OAuth 2.0 [RFC6749] 4.1.3节中 authorization_code 描述的一样。如果客户端是一个保密客户端,那么它必须使用验证方法验证令牌终结点注册的 client_id 值,如9节中描述一样。
客户端使用HTTP POST 方法和表单序列化参数发送给令牌终结点,在OAuth 2.0 [RFC6749] 13.2节 、4.1.3节中描述过。
下面是一个非规范化的令牌的请求:
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请求令牌验证(Token Request Validation)
授权服务器必须验证令牌请求如下:
- 对客户端进行验证,如果是发布客户端凭据或者使用另一个客户验证方法,第 9节定义;
- 确保授权码发布给验证过的客户端。
- 验证授权码是有效的。
- 如果可能的话,验证授权码是以前没有使用过的。
- 确保 redirect_uri 参数值是和最初的授权请求的 redirect_uri 参数值是相同的。如果 redirect_uri 参数值是一个不存在的redirect_uri注册值时,授权服务器可能返回一个错误 (因为客户端应该包括该参数) 也可能不返回错误 (因为OAuth 2.0在这种情况下允许参数被省略)。
- 验证所使用的授权码者和OpenID Connect 验证的请求发出者 (因此ID Token将从令牌终结点返回)。
3.1.3.3成功的令牌响应(Successful Token Response)
从客户机收到和验证一个有效的和授权的令牌的请求,授权服务器返回包含一个ID Token和一个Access Token的成功响应。在OAuth 2.0 [RFC6749] 4.1.4节参数定义成功的响应。响应使用 application/json 元数据类型。
在使用OAuth 2.0 (RFC6750)指定无记名令牌时OAuth 2.0 token_type 响应参数值必须是Bearer, 除非是另一个已经与客户协商好的令牌类型。服务器应该支持Bearer令牌类型; 使用其他类型的令牌超出本规范范围。
除了指定的OAuth 2.0的响应参数,下面参数必须包含在响应中:
id_token
与认证会话相关联的ID Token值。
包含令牌的所有令牌响应、密钥、或其他敏感信息必须包括以下HTTP响应头字段和值中:
Header Name | Header Value |
Cache-Control | no-store |
Pragma | no-cache |
下面是一个成功令牌响应的非规范化的例子:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"refresh_token": "8xLOxBtZp8",
"expires_in": 3600,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.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 (RFC6749)中,客户应该忽略未被认可的参数得响应。
3.1.3.4 令牌错误响应(Token Error Response)
如果令牌请求无效或未经授权,授权服务器构造错误响应。令牌的错误响应的参数被定义为在OAuth 2.0 [RFC6749] 5.2节。HTTP响应的body使用 application/json 媒体类型的HTTP 400响应。
下面是一个标记错误响应非规范化的例子:
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"error": "invalid_request"
}
3.1.3.5 令牌响应确认(Token Response Validation)
客户端必须验证令牌响应如下:
1、遵循RFC 6749的验证规则,特别是在5.1和10.12章节。
2、按照3.1.3.7 验证规则验证ID Token。
3、按照3.1.3.8验证规则验证Access Token。
3.1.3.6 ID Token
ID Token的内容在第二节中描述。当使用授权码流,以下声明申请ID Token为附加要求:
at_hash
可选的。Access Token的哈希值。其值是最左边的base64url编码的一半的哈希的八位字节ASCII表示 access_token 值,使用的哈希算法是在alg 头参数的 ID Token的JOSE Header中使用。例如,如果 alg 是RS256,使用SHA-256哈希的access_token值,然后把最左边的128位base64url编码。at_hash 值是大小写敏感的字符串。
3.1.3.7 ID Token验证(ID Token Validation)
客户必须使用下列方式验证令牌响应中的ID Token:
1、如果ID Token已加密,使用客户端在注册其间由OP使用的加密ID Token的密钥和算法解密。如果在注册OP时忽略加密和ID Token没有被加密,RP应该拒绝它。
2、发行OpenID提供者标识符 (这通常是在发现时获得) 必须精确匹配iss (发行人)声明。
3、客户端必须验证作为一个消费者在发行人确定的注册 iss (发行人)声明中包含有 client_id 值的aud (消费者)声明。aud (消费者)声明可能包含不止一个数组元素。如果ID Token列表中没有把客户端作为一个有效的消费者,或如果它包含额外的,客户端不信任的消费者,必须拒绝此ID Token。
4、如果ID Token包含多个消费者,客户端应该验证,azp (授权方) 声明是否存在。
5、如果 azp (授权方)声明存在,客户应该确认它 client_id 是否为声明值。
6、如果通过直接收到客户端和令牌终结点之间沟通(内部流程)的ID Token,TLS验证服务器可用于代替发布者验证检查令牌签名。客户端必须验证所有其他ID Token签名,通过jws 使用指定包含JWT alg 头参数加密算法。客户端必须使用由发行人提供的keys解密。
7. alg的值应该是默认的 RS256 或客户端在注册过程中通过 id_token_signed_response_alg 参数发送的算法。
8. 如果JWT alg 头参数使用一个基于MAC算法如 HS256 ,HS384 ,或 HS512 ,UTF-8的八位字节表示的client_secret 对应的包含aud (消费者)声明为key 的client_id来验证签名。基于MAC算法,其行为是未指定的,如果 aud 有多个值或如果 azp 值存在不同的 aud 值。
9、当前时间必须在exp(有效期)声明所代表的时间之前。
10、当发行超过有效时间期,iat 声明可以拒绝使用令牌,限制次数的nonces必须存储以阻止攻击。可接受的范围是特定的客户。
11、如果nonce值发送验证请求,一个 nonce 声明必须存在并且用它的值来验证检查与作为一个验证请求中发送的nonce是否为相同的值。客户端应该检查 nonce 值阻止重播攻击。这对阻止重播攻击特定客户有效方法。
12、如果有 acr 声明请求,客户机应该检查断言声明值是合适的。处理 acr 声明值的意义超出了本规范的范围。
13. 如果需要 auth_time 声明,通过一个特定的请求声明或通过使用max_age 参数,客户端应该检查 auth_time 声明的值,当最近的验证终端用户的验证时间太久,必须请求重认证。
3.1.3.8 Access Token验证(Access Token Validation)
当使用授权码流,如果ID Token包含一个 at_hash 声明,客户端可以用它来以同样的方式验证能过3.2.2.9中定义的隐式流程Access Token,但使用从令牌终结点返回ID Token和Access Token。