* 仕様書

[REFS[
- [1] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-1.3.1>
- [10] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-3.1.1>
- [12] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-4.1>
- [15] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-4.1.2>
- [23] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-4.1.3>
- [26] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-10.5>
- [30] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-10.8>
- [32] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#section-10.10>
- [33] [CITE@en[RFC 6749 - The OAuth 2.0 Authorization Framework]] ([TIME[2014-12-15 14:15:35 +09:00]] 版) <http://tools.ietf.org/html/rfc6749#appendix-A.11>
- [35] [CITE@en[RFC 6819 - OAuth 2.0 Threat Model and Security Considerations]] ([TIME[2015-02-10 06:43:00 +09:00]] 版) <http://tools.ietf.org/html/rfc6819#section-4.4.1.11>
]REFS]

* 認可符号

[2] [DFN[[RUBYB[認可符号]@en[authorization code]]]]は、[[資源所有者]]による[[認可]]を[[鯖]]から[[クライアント]]に知らせ、
[[クライアント]]が[[鯖]]から[[アクセストークン]]を得るための[[符号]]です。

[18] [[認可符号]]は、[[クライアント識別子]]および[[リダイレクトURL]]に束縛されています [SRC[>>15]]。

;; [[認可エンドポイント]]で発行される時に指定されていた値を保存する必要があります。
[[トークンエンドポイント]]で[[アクセストークン]]を発行する際に[[クライアント]]が指定した値と照合することになります。

[21] [[認可符号]]は、 [CODE(URI)@en[[[code]]]] [[引数]]の構文上の制約より、
1つ以上の[[印字可能ASCII文字]]の[[文字列]]である必要があります。

[22] [[認可符号]]の長さは [[OAuth]] 仕様としては定義されていません。
[[クライアント]]は長さに仮定を置くべきではありません。
[[認可鯖]]は発行する[[認可符号]]の長さを明文化する[['''べきです''']]。 [SRC[>>15]]

[31] [[認可鯖]]は、[[認可符号]]を推測できないものとしなければ[['''なりません''']] [SRC[>>32]]。
攻撃者が推測できる確率は 2[SUP[-128]] [[以下]]で[['''なければならず''']]、
2[SUP[-160]] [[以下]]である[['''べきです''']] [SRC[>>32]]。

[16] [[認可符号]]は、漏洩の危険を減らすため、発行して間もなく[[満期]]としなければ[['''なりません''']] [SRC[>>15, >>26]]。
[[寿命]]は最大でも10分とする[['''べきです''']] [SRC[>>15]]。

[27] [[認可符号]]の転送は、[[保安通信路]]で行う[['''べきです''']] [SRC[>>26, >>30]]。
[[クライアント]]は、[[ネットワーク]]の[[資源]]を識別する[[リダイレクトURL]]
を用いる場合は、 [[TLS]] の利用を求める[['''べきです''']] [SRC[>>26]]。
[[クライアント]]が[[資源所有者]]を[[認証]]するために[[認可符号]]に依存するのであれば、
[[TLS]] の利用を求めなければ[['''なりません''']] [SRC[>>26]]。

;; [41] [SHOULD[べき]]にとどまっているのは [[OAuth 2.0]] 制定当時の世間がそのような状況だったためと思われます。
現在ではそうしなければ[MUST[ならない]]と解釈するべきです。
現在の基準では、 [[TLS]] を使用しない通信が認められるべき状況はおよそ考えられません。

;; [28] [[認可符号]]は[[リダイレクト]]によって授受されますから、
[[利用者エージェント]]の[[履歴]]や [[Referrer]] の[[ヘッダー]]を通して漏れる可能性があります
[SRC[>>26]]。

[17] [[クライアント]]は[[認可符号]]を複数回使ってはなりません。
[[認可鯖]]は複数回使われたら要求を拒絶しなければ[['''ならず''']] [SRC[>>15, >>26]]、
その[[認可符号]]により以前に発行されたすべての[[トークン]]を (できれば)
取り消し ([[revoke]]) する[['''べきです''']] [SRC[>>15, >>26]]。

[29] [[認可鯖]]は[[クライアント認証]]が可能であれば、
[[認可符号]]が同じ[[クライアント]]に発行されたものか確認しなければ[['''なりません''']]
[SRC[>>26]]。

[38] 異なる[[クライアント]]の[[認可符号]]を使える場合、攻撃対象の[[クライアント]]がいわゆる[[OAuthログイン]]を実装している場合において、攻撃者の有する[[クライアント]]に攻撃対象の[[資源所有者]]を誘導して[[認可符号]]を取得し、その[[認可符号]]を攻撃対象の[[クライアント]]に与えることで、攻撃者が攻撃対象[[クライアント]]における攻撃対象[[資源所有者]]になりすまして[[ログイン]]できてしまいます [SRC[>>37]]。

;; [39] これを防ぐために[[OAuthログイン]]を使う[[クライアント]]は[[クライアント型]]を[[機密]]にし、[[トークンエンドポイント]]アクセス時に[[クライアント認証]]を行う必要があります。
[SEE[ [[トークンエンドポイント]] ]]

[REFS[
- [37] [CITE@en[RFC 6819 - OAuth 2.0 Threat Model and Security Considerations]] ([TIME[2015-02-10 06:43:00 +09:00]] 版) <http://tools.ietf.org/html/rfc6819#section-4.4.1.13>
]REFS]

[36] 攻撃者が[[認可鯖]]に[[認可符号]]を発行させる操作を大量に実行して[[認可符号]]を枯渇させるような[[DoS攻撃]]があり得ますから、
[[利用者]]ごとに発行数を制限するなど、対策を講じるべきです [SRC[>>35]]。

* 認可符号承諾フロー

[3] [[認可符号承諾フロー]]では、[[クライアント]]は、
[[資源所有者]]に直接[[認可]]を求めるのではなく、
まず[[認可鯖]]の[[認可エンドポイント]]へと[[資源所有者]]を[[リダイレクト]]します
[SRC[>>1, >>12]]。[[クライアント]]はこの時[[クライアント識別子]] 
([CODE(URI)@en[[[client_id]]]])、 [[適用範囲]] ([CODE(URI)@en[[[scope]]]])、
局所状態 ([CODE(URI)@en[[[state]]]])、[[リダイレクトURL]] ([CODE(URI)@en[[[redirect_uri]]]])
を指定します [SRC[>>12]]。

[4] [[認可鯖]]の[[認可エンドポイント]]は、
[[資源所有者]]を[[認証]]し、
[[クライアント]]によるアクセスの[[認可]]を[[資源所有者]]から得てから、
[[資源所有者]]を[[クライアント]]の[[リダイレクトエンドポイント]]へと[[認可符号]]や局所状態
([CODE(URI)@en[[[state]]]]) を添えて[[リダイレクト]]して戻します。 [SRC[>>1, >>12]]

[5] [[クライアント]]の[[リダイレクトエンドポイント]]は、
指定された[[認可符号]]を使って ([CODE(URI)@en[[[code]]]])
[[認可鯖]]の[[トークンエンドポイント]]に要求することで、
[[アクセストークン]]を得ることができます。この時[[クライアント]]は >>3
の[[リダイレクト]]に使った [[URL]] を指定し ([CODE(URI)@en[[[redirect_uri]]]])、
[[認可鯖]]はそれが[[認可符号]]を発行した
[[URL]] と一致しているか確認します。
[[認可鯖]]は[[アクセストークン]]と共に[[更新トークン]]を発行することもできます。 [SRC[>>12]]

[FIG(sequence)[
:R:[[資源所有者]]
:C:[[クライアント]]
:S:[[認可鯖]]
:R -> C:[[OAuth]] 処理開始の要求
:C -> R:[[認可エンドポイント]]への[[リダイレクト]]
:R -> S:[[認可エンドポイント]]への要求 ([CODE(URI)@en[[[response_type]]=[[code]]]])
:S -> R:[[クライアント]]によるアクセスを[[認可]]するか確認
:R -> S:[[クライアント]]によるアクセスの[[認可]]
:S -> R:[[リダイレクトエンドポイント]]への[[リダイレクト]] ([[認可符号]]つき)
:R -> C:[[リダイレクトエンドポイント]]への要求
:C -> S:[[トークンエンドポイント]]への要求
:S -> C:[[アクセストークン]]の発行
:C -> R:[[OAuth]] 処理完了の応答
]FIG]

[13] 本[[承諾型]]は[[リダイレクト]]を用いますから、必然的に[[クライアント]]は[[資源所有者]]の[[利用者エージェント]]
(通常は [[Webブラウザー]]) と対話できることと共に、[[リダイレクト]]によって[[認可鯖]]からやってくる要求を受信することができる必要があります [SRC[>>12]]。

;; [6] [[OAuth 2.0]] 仕様書は、“[[認可鯖]]を[[クライアント]]と[[資源所有者]]の間の[RUBYB[中間器]@en[intermediary]]として使う” [SRC[>>1]] と表現しています。
([[HTTP]] における[[中間器]] (≒ [[串]]) とは意味が異なります。)

;; [7] 本[[承諾型]]では[[資源所有者]]は[[認可鯖]]に対してのみ[[認証]]しますから、
[[資源所有者]]の [[credentials]] を[[クライアント]]が知る必要はありません [SRC[>>1]]。

[8] 本[[承諾型]]では ([[認可符号]]からの[[アクセストークン]]取得時に) 
[[認可鯖]]が[[クライアント]]を[[認証]]することができます [SRC[>>1]]
([CODE(URI)@en[[[client_id]]]] 参照)。
本[[承諾型]]は[[クライアント型]]が[[機密]]の場合に最適化されています [SRC[>>12]]。

;; [9] 本[[承諾型]]では[[資源所有者]]や第三者に晒さず直接[[クライアント]]に[[アクセストークン]]を渡すことができます [SRC[>>1]]。
[[Webブラウザー]]上で動作する[[スクリプト]]や [[Webブラウザー]]の脆弱性、
[[中間者攻撃]]、悪意ある[[資源所有者]]などによる漏洩を防ぐことができます。

;; [14] 本[[承諾型]]は [[OAuth 1.0]] に最も近い形をとっていますが、
[[OAuth 1.0]] の[[一時credentials要求]]に相当するものが不要になっています。

* [CODE(URI)@en[response_type=code]]

[11] [[OAuth 2.0]] [[認可エンドポイント]]の [CODE(URI)@en[[[response_type]]]]
[[引数]]の値 [DFN[[CODE(URI)@en[[[code]]]]]] は、
[[認可符号]]を求めていることを表します [SRC[>>10]]。

* [CODE(URI)@en[grant_type=authorization_code]]

[24] [[認可鯖]]の[[トークンエンドポイント]]の [CODE(URI)@en[[[grant_type]]]]
[[引数]]の値 [DFN[[CODE(URI)@en[[[authorization_code]]]]]] [SRC[>>23]] は、
[[認可符号]]から[[アクセストークン]]を得ることを[[クライアント]]が求めていることを表します。

* [CODE(URI)@en[code]] 引数

[19] [[クライアント]]の[[リダイレクトエンドポイント]]の
[DFN[[CODE(URI)@en[[[code]]]]]] [[引数]]は、[[認可鯖]]が発行した[[認可符号]]を表します。

[34] この[[引数]]の値は、1文字以上の[[印字可能ASCII文字]]の列です [SRC[>>33]]。

[20] [[認可鯖]]が[[認可符号承諾フロー]]で[[リダイレクトエンドポイント]]に[[リダイレクト]]する時は、
[[リダイレクトURL]]に [CODE(URI)@en[[[code]]]] [[引数]]を追加しなければ[['''なりません''']]
[SRC[>>15]]。

[25] [[認可鯖]]の[[トークンエンドポイント]]の [CODE(URI)@en[[[code]]]]
[[引数]]には、[[リダイレクトエンドポイント]]の [CODE(URI)@en[[[code]]]] [[引数]]によって受信した[[認可符号]]を指定しなければ[['''なりません''']] [SRC[>>23]]。

* メモ

[40] [CITE@en[Final: OpenID Connect Core 1.0 incorporating errata set 1]]
([TIME[2014-11-09 04:00:29 +09:00]] 版)
<http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth>