[29] [[OAuth 1.0]] の規定に従い[[要求引数]]を追加した [[HTTP要求]]を、
[DFN[[RUBYB[[[認証された要求]]]@en[authenticated request]]]]といいます。
認証された要求には [[OAuth 1.0]] による[[要求URL]]と[[引数]]の[[署名]]が含まれており、
[[鯖]]は正しい[[クライアント]]によって生成された[[要求]]であるかを[[検証]]できます。

[48] [[OAuth 1.0]] では、最初の[[資源所有者]]に[[認可]]を求め[[アクセストークン]]を得る手続きとそれ以後の[[アクセストークン]]を使って
[[Web API]] にアクセスする段階の両方で[[認証された要求]]を使います。
稀に本来の [[OAuth 1.0]] 以外でも本方式を流用していることがあります。

;; [49] [[認証された要求]]は、[[クライアント]]が[[鯖]]に送信する際に[[署名]]するものです。
逆に[[鯖]]から[[クライアント]]に送信する[[応答]]では、これに類するものは使いません。
また[[クライアント]]と[[資源所有者]]や[[鯖]]と[[資源所有者]]とのやり取りでも、使いません。

* 仕様書

[REFS[
- [31] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]] ([TIME[2014-12-28 14:19:21 +09:00]] 版) <http://tools.ietf.org/html/rfc5849#section-2.1>
- [4] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]] ([TIME[2014-12-28 14:19:21 +09:00]] 版) <http://tools.ietf.org/html/rfc5849#section-2.3>
- [1] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]] ([TIME[2014-12-28 14:19:21 +09:00]] 版) <http://tools.ietf.org/html/rfc5849#section-3>
-- [6] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]] ([TIME[2014-12-28 14:19:21 +09:00]] 版) <http://tools.ietf.org/html/rfc5849#section-3.1>
-- [18] [CITE@en[RFC 5849 - The OAuth 1.0 Protocol]] ([TIME[2014-12-28 14:19:21 +09:00]] 版) <http://tools.ietf.org/html/rfc5849#section-3.2>
- [39] [CITE@en[Final: OAuth Request Body Hash]] ([TIME[2009-04-12 08:08:27 +09:00]] 版) <http://oauth.googlecode.com/svn&l=52/spec/ext/body_hash/1.0/oauth-bodyhash.html#anchor7>
]REFS]

* 意味

[2] [RUBYB[[[認証された要求]]]@en[authenticated request]]には、 [[クライアント]]を表す[[クライアントcredentials]]と、
[[資源所有者]]を表す[[トークンcredentials]]を含めます [SRC[>>1]]。

[3] [[認証された要求]]の作成に当たっては[[鯖]]の設定に関する事前の知識が必要です。
[[クライアント]]が[[鯖]]の要求する設定をどう[[発見]]するかは [[OAuth]]
仕様の範囲外とされています。 [SRC[>>1]]

;; [30] 具体的には、どの[[署名方式]]に対応しているかを知っている必要があります。

* 作成

[7] [[認証された要求]]は、[[HTTP要求]]に次のように[[引数]]を加えて作成します。

[FIG(steps)[
= [8] 次の[[引数]]を用意します。
[FIG(list members)[
:[9] [CODE(HTTP)@en[[[oauth_consumer_key]]]]:[[クライアントcredentials]]の[[識別子]] [SRC[>>6]]。
:[10] [CODE(HTTP)@en[[[oauth_token]]]]:[[資源所有者]]を関連付けるための[[トークン]]の値。
[[資源所有者]]と関連付けない場合には、省略して構いません。 [SRC[>>6]]
:[11] [CODE(HTTP)@en[[[oauth_signature_method]]]]:
[[クライアント]]が使う[[署名方式]]の名前 [SRC[>>6]]。
:[12] [CODE(HTTP)@en[[[oauth_timestamp]]]]:[[タイムスタンプ]]。
ただし [CODE(HTTP)@en[[[oauth_signature_method]]=[[PLAINTEXT]]]] なら、
省略して構いません。 [SRC[>>6]]
:[13] [CODE(HTTP)@en[[[oauth_nonce]]]]:[[nonce]] 値。
ただし [CODE(HTTP)@en[[[oauth_signature_method]]=[[PLAINTEXT]]]] なら、
省略して構いません。 [SRC[>>6]]
:[14] [CODE(HTTP)@en[[[oauth_version]]]]:[CODE(HTTP)[[[1.0]]]]。
省略しても構いません。 [SRC[>>6]]
:[40] [CODE(HTTP)@en[[[oauth_body_hash]]]]:指定するべき場合には、
仕様に従い計算した値 [SRC[>>39]]。 ([CODE(HTTP)@en[[[oauth_body_hash]]]] 参照。)
]FIG]
= [15] 用意した[[引数]]を、[[転送方式]]のいずれかにより[[要求]]に追加します。 [SRC[>>6]]
= [16] [CODE(HTTP)@en[[[oauth_signature]]]] の値を計算します。 [SRC[>>6]]
= [17] [CODE(HTTP)@en[[[oauth_signature]]]] [[引数]]を >>15 で選択した[[転送方式]]により[[要求]]に追加します。 [SRC[>>6]]
]FIG]

[42] [CODE(HTTP)@en[[[oauth_signature_method]]=[[RSA-SHA1]]]] では、
[CODE(HTTP)@en[[[xoauth_signature_publickey]]]] [[引数]]や
[CODE(HTTP)@en[[[xoauth_public_key]]]] [[引数]]も指定されることがあります。

[32] [[一時credentials要求]]では、[[クライアント]]が[[鯖]]に[[認証された要求]]を送信しますが、
この時は[[クライアントcredentials]]だけ使い、[[トークンcredentials]]は指定しません [SRC[>>31]]。

[5] [[トークン要求]]では、[[クライアント]]が[[鯖]]に[[認証された要求]]を送信しますが、
この時は[[クライアントcredentials]]と共に ([[トークンcredentials]]のかわりに)
[[一時credentials]]を使います [SRC[>>4]]。

[36] [[xAuth]] では [CODE(URI)@en[[[oauth_token]]]] を使わず、
[CODE(HTTP)@en[[[HMAC-SHA1]]]] 計算時の[[トークン共有秘密]]は[[空文字列]]とします
[SRC[>>35]]。

[33] [[Google]] の [[2-legged OAuth]] では、
[CODE(URI)@en[[[oauth_token]]]] を使わず、代わりに
[CODE(URI)@en[[[xoauth_requestor_id]]]] を使うことになっていました。
ただし [CODE(URI)@en[[[xoauth_requestor_id]]]] は [CODE(HTTP)@en[[[Authorization:]]]]
[[ヘッダー]]ではなく、 [[URL query]] に指定します。 [SRC[>>34]]

[38] [[Bitbucket]] や [[Mobage]] [SRC[>>47]] の [[2-Legged OAuth]] では、
[CODE(URI)@en[[[oauth_token]]]] とトークン秘密を使わないことで、
[[consumer]] として操作することを表すようです。

[44] [[mixi]] から外部[[アプリケーション]]サイトへの[[署名]]つき[[要求]]は、
[CODE(URI)@en[[[oauth_token]]]] を使わず、 [CODE(HTTP)@en[[[oauth_signature_method]]=[[RSA-SHA1]]]]
により[[公開鍵]]方式で[[署名]]しています [SRC[>>43, >>45, >>46]]。

[REFS[
- [35] [CITE[xAuth | Twitter Developers]] ([TIME[2015-03-05 11:30:55 +09:00]] 版) <https://dev.twitter.com/oauth/xauth>
- [34] [CITE@ja[OAuth 1.0 for Web Applications - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-12-12 09:19:57 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth#GoogleAppsOAuth>
- [46] [CITE@ja[署名付きリクエストの検証 << mixi Developer Center (ミクシィ デベロッパーセンター)]] ([TIME[2015-01-09 16:42:04 +09:00]] 版) <http://developer.mixi.co.jp/appli/spec/pc/validating_signed_requests/>
- [45] [CITE@ja[アクセスユーザの取得とOAuth Signatureの検証 << mixi Developer Center (ミクシィ デベロッパーセンター)]] ([TIME[2015-01-09 16:42:00 +09:00]] 版) <http://developer.mixi.co.jp/appli/spec/touch/getting_userid_and_verify_signature/>
- [43] [CITE@ja[Firefox 22 での Cookie有効化について << mixi Developer Center (ミクシィ デベロッパーセンター)]] ([TIME[2015-01-09 16:40:08 +09:00]] 版) <http://developer.mixi.co.jp/appli/ns/pc/firefox_22_cookie/>
- [47] [CITE[リクエストの署名 - Smartphone App - Mobage Developers Documentation Center]] ([TIME[2015-03-06 00:48:38 +09:00]] 版) <https://docs.mobage.com/display/JPSA/REST_API_Signing_Request_JP>
]REFS]

* [RUBYB[検証]@en[verify]]

[19] [[鯖]]は、[[認証された要求]]を受信したら、次のように[RUBYB[妥当性検証]@en[validate]]しなければ[['''なりません''']]。
[FIG(list)[
- [20] [[要求]]の[[署名]]を独自に計算し、 [CODE(HTTP)@en[[[oauth_signature]]]]
で指定された値と比較します。 [SRC[>>18]]
- [21] [[署名方式]]として [CODE(HTTP)@en[[[HMAC-SHA1]]]] や
[CODE(HTTP)@en[[[RSA-SHA1]]]] が使われていれば、
[CODE(URI)@en[[[oauth_nonce]]]], [CODE(URI)@en[[[oauth_timestamp]]]],
[CODE(URI)@en[[[oauth_token]]]] の値 (あれば) の組み合わせについて、
以前[[クライアント]]が使ったものと一致していないことを確認します。 [SRC[>>18]]
- [22] [CODE(URI)@en[[[oauth_token]]]] があれば、
[[クライアント]]の[[認可]]の範囲と状態を[RUBYB[検証]@en[verify]]します。 [SRC[>>18]]
- [23] [CODE(URI)@en[[[oauth_version]]]] があれば、値が [CODE(URI)[[[1.0]]]]
か確認します。 [SRC[>>18]]
]FIG]

[41] [CODE(URI)@en[[[oauth_body_hash]]]] [[引数]]が適用される場合には、
独自に計算し、指定された値と比較します。あるいは禁止されている場合に
[CODE(URI)@en[[[oauth_body_hash]]]] が指定されていないことを確認します。 [SRC[>>39]]

;; [CODE(URI)@en[[[oauth_body_hash]]]] も参照。

[24] この[RUBYB[検証]@en[verification]]に失敗した場合には、
適切な[[状態符号]]で[[応答]]を返す[['''べきです''']]。
[[payload body]] に拒絶の理由の詳細を含めて構いません。 [SRC[>>18]]

[27] [CODE(URI)@en[[[oauth_timestamp]]]] がある程度古ければ、
[[鯖]]は拒絶しても構いません。

[25] 未対応の[[引数]]、未対応の[[署名方式]]、[[引数]]の不足、
[[OAuth]] [[引数]]の重複が見られる時は、 [CODE(HTTP)[[[400]]]]
[[応答]]を返す[['''べきです''']] [SRC[>>18]]。

[26] 非妥当な[[クライアントcredentials]]、
非妥当な[[トークン]]や[[満期]]した[[トークン]]、
非妥当な[[署名]]、
非妥当な [[nonce]] や使用済みの [[nonce]] の時は、
[CODE(HTTP)[[[401]]]] [[応答]]を返す[['''べきです''']] [SRC[>>18]]。

[37] [[OAuth 1.0]] 本体仕様としてはエラー時の応答についてこれ以上の詳細は規定していません。
[[OAuth Problem Reporting Extension]] は報告方法を規定しており、
実装によってはこれに対応しています。

* 関連

[28] [[署名方式]]、[[要求引数]]も参照。

[50] [[OAuth 2.0]] では[[認証された要求]]に相当する概念はなくなっています。

[51] [[AWS4]] も同趣旨の署名を行うものですが、まったく互換性はありません。
