転送方式

引数 (OAuth 1.0)

[2] OAuth 1.0 ではプロトコルを構成する名前と値の組のことを引数 (parameter) と呼んでいます。

仕様書

構文

[3] 引数には、

... があります。

[8] OAuth 1.0multipart/form-data その他の MIME型は使いません。

引数の一覧

[30] 次の引数があり、 Authorization:URL query、または payload bodyクライアントにより使われます。

[31] 次の引数があり、 payload bodyにより使われます。

[59] 次の引数があり、 Authorization:payload bodyにより使われます。

[32] 次の引数があり、資源所有者にアクセスさせる URL (コールバックURL) の query または payload body で指定します。

[60] 次の引数があり、コールバックエンドポイントpayload body で指定します。

[22] 一時credentials要求資源所有者認可トークン要求で使うエンドポイントURLquery を含んでいても構いませんが、 oauth_ から始まる引数を含んではなりません >>21

[58] 実際に用いられている OAuth の拡張や独自の引数oauth_ から始まらないものについては、各エンドポイントの項を参照。

[29] Authorization:WWW-Authenticate: ヘッダーでは realm 引数を使うことができます。 これは HTTP の通常の意味により解釈されるもので、 OAuth としての特別な意味は持っていません。

[33] これらの引数の名前は、大文字と小文字を区別するようです。ただし Authorization:WWW-Authenticate:auth-param では大文字・小文字不区別となるので、 注意が必要です。

[34] 実装が大文字での指定も正しく扱えるのかは不明です。クライアント大文字混じりの Authorization: を生成することは明示的に禁じられていません。 ただし署名基底文字列では小文字でなければならないと思われます。 大文字混じりの Authorization: を受信した時にどう署名基底文字列を生成するべきなのかは明らかではありません。

要求引数

[9] 認証された要求では、次の引数のことを要求引数 (request parameter) >>1 と呼んでいます。要求引数署名の対象内となります。

  1. [11] 要求Authorization: OAuth ヘッダーrealm 以外の引数の名前と値の組
  2. [12] 要求Content-Type:application/x-www-form-urlencoded の場合、 payload body をそう解釈した時の名前と値の組
  3. [10] 要求URLqueryapplication/x-www-form-urlencoded として解釈した時の名前と値の組

[23] 認証された要求では、 oauth_ から始まる引数は、 この3つの指定方法 (転送方法 (transmission method) ) のいずれか一つのみで指定しなければなりません >>20Authorization: を使うのが一番好ましく、 query を使うのが一番好ましくありません >>20

[24] 将来の拡張により他の方法が用意される可能性もあります >>20。 (現実には極めて低いでしょうが。。。)
[25] oauth_ 引数をどの方法で転送したとしても、 署名基底文字列にはすべての方法で指定されたすべての引数が含まれます。
[41] クライアントがいずれか1つの転送方式を使うことが要求されていますが、 が複数の転送方式で指定された要求を拒絶することは要求されていないようです。 実際のところ引数ごとに別の転送方法を使うクライアントも存在していて、 それを拒絶しないも存在しているようです。
[51] 一時credentials要求トークン要求を除き、一般の認証された要求では OAuth で規定されない引数oauth_ で始まることも禁止されているわけではないようです。 しかし >>23 の規定により、 OAuth の規定に基づき符号化されることが要求されています。 OAuth で規定されていない引数が (偶然にも!) OAuth で規定されている引数と同じ名前を持つことは、 仕様書の表現上厳密には禁止されていないとも解釈できますが、 そのような要求は常識的に考えれば禁止されているとみなすべきでしょう (検証401 を返すべきとされています)。 (普通仕様書の行間を読むべきではありませんが、 IETF の仕様書は曖昧なことがよくあるので仕方ありません。)

[66] Evernoteヘッダーまたは URL query での指定に対応していると記述されており >>65payload body での指定に対応していないと思われます。

[13] 要求引数は、署名基底文字列の一部となります。 その際 oauth_signature 引数は、 署名基底文字列には含めてはなりません >>1。 また省略可能な引数を省略する場合には、 署名基底文字列に含めてはなりません >>1

[14] 署名基底文字列の作成時には application/x-www-form-urlencodedパーセント符号化+復号しますが、 Authorization: ヘッダー引数はそのまま復号せずに使います >>1

[46] application/x-www-form-urlencoded の復号の方法として HTML 4.0 (なぜか HTML 4.01 ではありません。) のフォームデータ集合の構築の項が参照されています >>1 が、 そこでは符号化の方法しか規定されておらず、実際にどう処理するべきなのかは明らかではありません。 非ASCII文字バイト列は符号化の方法すら示していないので、 どのように復号するのが正しいのかまったく不明です。

[47] 常に UTF-8 を用い、 UTF-8 として解釈できないバイト列URL queryapplication/x-www-form-urlencoded では使わないことにするのが相互運用性が高そうですが、 どのクライアントもそれで問題なく動作するのかは定かではありません。

問題を表す引数

[62] OAuth Problem Reporting Extension >>61 は問題の発生をからクライアントに通知するためのいくつかの引数を規定しています。

[63] は、任意のHTTP応答にこれを含めることができます。 WWW-Authenticate: OAuthauth-param として指定するべきです。 payload body にも指定できます。 両方指定する場合は、同一にするべきです。 >>61

要求引数の正規化

[15] 要求引数正規化 (normalization) は、次のように行います >>1

  1. [16]引数の名前と値をそれぞれOAuth 1.0パーセント符号化します。
  2. [17] 引数を名前の昇順整列します。同名の引数が複数あれば、 値で整列します。
  3. [18] 名前と値を = で連結します。
  4. [19] 引数& で連結します。

[52] この正規化結果の値は、署名基底文字列の一部として使われます。

[69] 要求引数クエリー要求本体では application/x-www-form-urlencoded符号化されますが、 ここでは OAuth 1.0パーセント符号化されます。両者の結果は微妙に違うので注意が必要です。

[67] signature base string の計算時に引数はパーセント符号化してから整列されますが、 整列してからパーセント符号化する実装があり、正しいサーバーとやりとりできなかったりします。

[68] Perlモジュール OAuth::Lite はその扱いがおかしく、 同名の引数ASCII文字のみの値と非ASCII文字 (などパーセント符号化されるような文字) の値が混在していると正しく署名を計算できないようです。

[73] この辺 RFC になる前の OAuth 1.0a 仕様書と RFC とで記述が少し変わっていて、古い仕様書では不明瞭なため意図に反した実装があったので RFC で明確化されたものだと思われます。

[74] 正しい仕様に修正しようとしてもバグ互換性のために古い挙動を維持していることもある >>72 ようで、 不具合が長期間継続して放置されている事例もみられます >>71, >>70

[70] 【開発者向け情報】はてなブックマーク REST API で特定条件下においてブックマークの追加・更新に失敗する不具合を修正しました - はてなブックマーク開発ブログ () http://bookmark.hatenastaff.com/entry/2019/03/06/121008

本APIへのリクエストの検証のために内部的に利用している、OAuth関連ライブラリの旧バージョンにおける実装が、OAuth 1.0 の仕様を定義した RFC5849 の パラメータ正規化の仕様に厳密には沿っておりませんでした。そのため、APIのパラメータの仕様によっては、リクエストの検証のためにサーバーサイドで生成したoauth_signatureが、クライアントが生成したものと食い違う場合がありました。

Authorization: OAuthauth-param による引数の指定

[26] Authorization: ヘッダーを使って要求引数を表す場合や WWW-Authenticate: ヘッダーを使って引数を表す場合、 その HTTP credentialsHTTP における auth-param 構文よりも厳しい制限があります。また名前と値はOAuth 1.0パーセント符号化されます。

auth-param を参照。なおこの制約は credentials のみで、 challenge には適用されないようです。

[27] realm 引数HTTP 仕様に従い指定しても構いませんし、 省略しても構いません >>20

[28] しかし指定されていないと壊れる実装もあるようです。
realm も参照してください。

[40] oauth_ 引数Authorization: 以外の方法で指定する場合に Authorization: ヘッダーを含めることは禁止されてはいません。 oauth_ 引数を複数の方法で指定することは禁止されているので、それ以外の引数 (realm) しか指定できなくなります。

[48] この方法で指定された引数がどのように処理するべきかについて、 仕様上明記されていません。 HTTP 仕様に従って処理した後、 OAuth 1.0パーセント符号化復号する必要がありますが (auth-param 参照)、どのように処理されるか不明なため、 記号非ASCII文字を使うのは避けた方が安全かもしれません。

payload body による引数の指定

[35] payload body によって引数を表す場合、 Content-Type: ヘッダーapplication/x-www-form-urlencoded でなければなりません >>20

[36] 仕様上明示されていませんが、 charset 引数Content-Type: ヘッダーに指定する実装もあるようです (が意味はありません)。
[64] OAuth Problem Reporting Extension にも適用されるかどうかは仕様上不明瞭ですが、 適用されると解釈するべきでしょう。

[37] payload body には他の (OAuth 以外の) 引数を指定しても構いません。 その場合 OAuth引数は最後に置くべきです>>20

[42] Content-Type: がない場合や他の MIME型の場合は、 payload bodyOAuth引数とはみなされません。

[43] RFCpayload bodyHTML 4.0application/x-www-form-urlencoded の符号化方法で符号化されたものでない場合にも要求引数とはみなさない >>1 としていますが、実装がそこまで検査しているかは疑問があるところです。 HTML 4.0非ASCII文字の符号化方法を明記していないので、 そのようなデータは合致しないことになってしまいますが、 流石にそれでは実情に合いません。

[45] それ以外の、構文的に正しくない application/x-www-form-urlencoded がどう処理されるかなどは未知数です。
[44] なぜか当時最新の HTML 4.01 ではなく HTML 4.0 が参照されています。

[49] この方法で指定された引数がどう処理するべきかは仕様書には明記されていませんが、 application/x-www-form-urlencoded の規定に従うと解釈するのが自然でしょう。

URL query による引数の指定

[38] URL query によって要求引数を表す場合、 他の (OAuth 以外の) 引数を指定しても構いません。 その場合 OAuth引数は最後に置くべきです>>20

[39] query の他の部分の制約はなく、 application/x-www-form-urlencoded になってなくても構わないようです。 (ただし署名基底文字列の計算時には application/x-www-form-urlencoded として解釈されます。)

[50] この方法で指定された引数がどう処理するべきかは仕様書には明記されていません。 application/x-www-form-urlencoded の規定に従い解釈すれば、 適切に処理できます。

HTTP キャッシュとの関係

[54] HTTPキャッシュAuthorization: ヘッダーがあると原則としてキャッシュ不可能と判断しますが、 URL querypayload body によって要求引数を指定すると (他の条件にもよりますが) キャッシュ可能と判断します。 Cache-Control: ヘッダーを適切に設定するなど配慮が必要です >>53

[55] OAuth を実装するライブラリーの類は、どのような環境で使われるか事前にわからないので、 Authorization: OAuthCache-Control: private など適切なヘッダーを付与するのを既定の動作とするのが望ましいと思われます。

関連

[57] 引数 (OAuth 2.0) は似ていますが、若干違っています。

メモ