/
374.txt
275 lines (202 loc) · 19 KB
/
374.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
[10] [DFN[[RUBYB[[[クライアントcredentials]]]@en[client credentials]]]]は、
[[OAuthクライアント]]を識別、認証するための [[credentials]] です。
* 仕様書
[REFS[
- [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-1.1>
- [3] [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>
-- [7] [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>
-- [9] [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.4.2>
- [11] [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-4.6>
- [15] [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-4.15>
- [17] [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.4>
- [20] [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-2>
-- [21] [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-2.2>
-- [34] [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-2.3>
- [55] [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.2.1>
- [57] [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.1>
- [59] [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.1>
- [60] [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.2.1>
- [61] [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.4>
- [37] [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>
- [39] [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.1>
- [41] [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.2>
]REFS]
* クライアントの登録
[5] [[OAuth 1.0]] では、[[認証された要求]]の作成に先立って[[クライアント]]と[[鯖]]との間で[[クライアントcredentials]]
を準備しておく必要があります [SRC[>>3]]。
[24] [[OAuth 2.0]] では、利用に先立って[[クライアント]]は[[認可鯖]]に自身を登録することになっています
[SRC[>>20]]。
[[認可鯖]]は、登録された[[クライアント]]に[[クライアント識別子]]を発行します。
[27] しかしその具体的な方法は、 [[OAuth 1.0]] [SRC[>>3]] も [[OAuth 2.0]] [SRC[>>20]]
も仕様の範囲外としています。
;; [6] 一般的には、当該[[Webアプリケーション]]の管理画面等で[[クライアント]]を登録することで、
[[クライアントcredentials]]が生成されるという形が採られています。
;; [25] しかし[[クライアント]]と[[認可鯖]]が直接やり取りして登録する必要はなく、
自己または第三者の発行する表明に基づいたり、
信頼できる通信路によるクライアント発見法を用いたりしても構いません。 [SRC[>>20]]
[26] [[OAuth 2.0]] [[クライアント]]の登録においては、
[[クライアント]]の開発者が次の情報を提供しなければ[['''なりません''']] [SRC[>>21]]。
[FIG(list members)[
- [28] [RUBYB[[[クライアント型]]]@en[client type]] (必須)
- [29] [RUBYB[[[クライアントリダイレクトURL]]]@en[client redirection URL]] (ほとんどの場合)
- [30] その他[[認可鯖]]が必要な情報 (例えば[[応用]]名、
[[Webサイト]]、説明文、[[ロゴ]]、規約への同意など)
]FIG]
[48] [[OAuth 1.0]] は未登録の[[クライアント]]の利用に言及していませんでした。
[[OAuth 2.0]] は未登録の[[クライアント]]の利用を排除していませんが、
[[OAuth 2.0]] 仕様の範囲外ともしています [SRC[>>20]]。
[69] [[Google]] は [[OAuth 1.0]] 時代に [[consumer key]] と [[consumer secret]]
を共に [CODE[anonymous]] として [CODE(URI)@en[[[oauth_signature_method]]=[[HMAC-SHA1]]]]
を使う [SRC[>>68]] ことで、未登録の[[クライアント]]の利用を認めていました。
[REFS[
- [68] [CITE@ja[OAuth 1.0 API Reference - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-12-05 11:52:26 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth_ref#SigningOAuth>
]REFS]
[35] 更に [[OAuth 2.0]] は[[クライアント型]]が[[機密]]の[[クライアント]]に対して[[トークンエンドポイント]]で[[クライアント認証]]を求めており、また[[クライアント型]]が[[公開]]の[[クライアント]]も[[クライアント認証]]することを認めています。従って[[認可鯖]]および[[クライアント]]はそのための情報も保持する必要があります。
;; [[クライアント認証]]を参照。
[36] [[資源所有者合言葉credentials]]は、他の[[承諾型]]よりも限定的に用いるべきだとされています。
従って[[認可鯖]]は、[[クライアント]]が[[資源所有者合言葉credentials]]
を利用できるかどうかのフラグも保持する必要があります。
;; [[資源所有者合言葉credentials]]参照。
[67] [[OpenID Connect]] は[[クライアント登録]]のための [[API]] の規定を含んでいます。
* OAuth 1.0 クライアント credentials
[4] [[クライアントcredentials]]は、
[RUBYB[[[固有識別子]]]@en[unique identifier]]と、
[RUBYB[[[共有秘密]]]@en[shared-secret]]
([DFN[[RUBYB[[[クライアント共有秘密]]]@en[client shared-secret]]]] [SRC[>>9]]) か
[RUBYB[[[RSA鍵組]]]@en[RSA key pair]] ([[RSA公開鍵]]と[[RSA秘密鍵]])
によって構成されます [SRC[>>3]]。
;; [2] 元は[[クライアント識別子]]のことを [DFN[[[consumer key]]]]、
[[クライアント共有秘密]]のことを [DFN[[[consumer secret]]]]
と呼んでいました [SRC[>>1]]。
[52] [[クライアント識別子]]は、[[認証された要求]]において[[クライアント]]を識別するために
[CODE(URI)@en[[[oauth_consumer_key]]]] [[引数]]で使います。
[32] [[クライアント共有秘密]]は、 [CODE(HTTP)@en[[[oauth_signature]]=[[HMAC-SHA1]]]]
や [CODE(HTTP)@en[[[oauth_signature]]=[[PLAINTEXT]]]] で使います。
[[RSA鍵]]は、 [CODE(HTTP)@en[[[oauth_sianature]]=[[RSA-SHA1]]]] で使います。
;; [53] [[共有秘密]]と鍵の組の両方を保持する必要はありません。
用いない[[署名方式]]のものは不要です。
[54] [[クライアント識別子]]は、秘密ではありません。
[12] [[共有秘密]]や [[RSA秘密鍵]]は、[[クライアント]]が秘密に保持しておく必要があります。
[[共有秘密]]は[[鯖]]も[[署名]]の計算のために保持しておく必要があります。
;; [CODE(HTTP)@en[[[oauth_signature]]=[[PLAINTEXT]]]] では[[共有秘密]]が[[要求]]の一部として転送されます。
[13] [[クライアント]]が[[ネイティブアプリケーション]]で[[実行ファイル]]が配布される場合のように、
[[クライアントcredentials]]を攻撃者が入手できてしまう場合もあります。
[[鯖]]は[[クライアント]]の[RUBYB[識別]@en[identity]]の[RUBYB[検証]@en[verify]]に[[クライアントcredentials]]だけでなく、
可能なら[[IPアドレス]]その他の要素も考慮する[RUBYB[べき]@en[should]]です。 [SRC[>>11]]
;; [14] [[実行ファイル]]が配布されるパターンで [[IPアドレス]]をチェックしても何の意味も無い気がしますが・・・。
不特定多数に配布される[[ネイティブアプリケーション]]を[[クライアント]]として [[OAuth 1.0]]
[[Web API]] を利用する場合には[[クライアントcredentials]]は意味を持たないものとして諦める以外に有効な策は無さそうです。
;; [16] [[資源所有者認可]]で[[資源所有者]]に明示的に確認せずに[[トークンcredentials]]
が発行されるような実装になっていると、公開されている[[クライアントcredentials]]
を使って第三者が[[トークンcredentials]]を取得できてしまい、特に危険です [SRC[>>15]]。
([[資源所有者認可]]も参照。)
;; [33] [[OAuth 2.0]] ではこの性質を[[クライアント型]]と呼んで分類しており、
[[クライアントcredentials]]を秘匿できない場合も考慮されています。
* OAuth 2.0 クライアント識別子
[31] [[認可鯖]]は、登録された[[クライアント]]に対して[DFN[[RUBYB[[[クライアント識別子]]]@en[client identifier]]]]を発行します。
[[クライアント識別子]]は、[[クライアント]]が提供した登録情報を表す、
[[認可鯖]]について固有の[[文字列]]です。 [SRC[>>20]]
[43] 使用できる[[文字]]は、[CODE(URI)@en[[[client_id]]]] [[引数]]の構文上の制約のため、
[[印字可能ASCII文字]]に限られます。
[22] [[クライアント識別子]]は、秘密ではありません。これ単独で[[クライアント]]の[[認証]]に使っては[['''なりません''']]。 [SRC[>>20]]
[23] [[クライアント識別子]]の長さは [[OAuth]] 仕様としては未定義となっています。
[[クライアント]]は仮定を置くべきではありません。
[[認可鯖]]は長さを文書化する[['''べきです''']]。 [SRC[>>20]]
[81] [[SurveyMonkey]] は [CODE(URI)@en[[[client_id]]]] を[[利用者名]]とし、
[CODE(URI)@en[[[client_secret]]]] と [CODE(URI)@en[[[api_key]]]] を[[鯖]]が発行した値としています [SRC[>>80]]。
[CODE(URI)@en[[[api_key]]]] は公開の値なので、広義の[[クライアント識別子]]を構成するものと言えますが、なぜ
[CODE(URI)@en[[[client_id]]]] と2つ指定させているのかは不明です。
[REFS[
- [80] [CITE@en[SurveyMonkey - Guide OAuth]] ([TIME[2015-03-05 17:23:37 +09:00]] 版) <https://developer.surveymonkey.com/mashery/guide_oauth>
]REFS]
;; [79] [[クライアント認証]]も参照。
* OAuth 2.0 クライアント認証
[65] [[トークンエンドポイント]]では、[[クライアント識別子]]と [[credentials]]
を使った[[クライアント認証]]が行われます。
;; [[トークンエンドポイント]]を参照。
* OAuth 2.0 クライアント credentials 承諾型
[18] [[OAuth 2.0]] [[承諾型]]としての[[クライアントcredentials]]は、
[[クライアントcredentials]] (やその他の形の[[クライアント]]の[[認証]])
を[[認可承諾]]として使うものです [SRC[>>17, >>61]]。
[19] 本[[承諾型]]は、[[認可]]の[[適用範囲]] ([[scope]])
が[[クライアント]]の制御下にある[[被保護資源]]に限定される時
[WEAK[([[クライアント]]が[[資源所有者]]でもある時)]] や、
他の[[資源所有者]]の制御下にある[[被保護資源]]であっても[[認可鯖]]との間で
([[OAuth]] の仕様外の何らかの方法で) 事前の取り決めがある時に使うことができます
[SRC[>>17, >>61]]。
[62] 本[[承諾型]]は、[[クライアント型]]が[[機密]]の場合以外は使っては[['''なりません''']]
[SRC[>>61]]。
[63] [[クライアント]]はまず[[認可鯖]]の[[トークンエンドポイント]]に[[アクセストークン]]の要求を送信します。
[[認可鯖]]は[[クライアント認証]]を行ってから、[[アクセストークン]]を発行します。 [SRC[>>61]]
[FIG(sequence)[
:C:[[クライアント]]
:S:[[認可鯖]]
:C -> S:[[トークンエンドポイント]]に[[アクセストークン]]を要求
:S -> C:[[アクセストークン]]を発行
]FIG]
[72] [[Azure]] が実装しています [SRC[>>71]]。事前に登録した ID と鍵の組を使うようです。
[74] [[Twitter]] が実装しています [SRC[>>73]]。 [[consumer key]] と [[consumer secret]]
を使うようです。
[76] [[Spotify]] が実装しています [SRC[>>75]]。
[78] [[reddit]] は「Application Only OAuth」として [CODE(URI)@en[[[gran_type]]=[[client_credentials]]]]
と [CODE(URI)@en[[[grant_type]]=[DFN[[[https://oauth.reddit.com/grants/installed_client]]]]]]
を利用しています。前者は[[機密]]の[[クライアント]]としてアクセスする場合に、
後者は[[公開]]の[[クライアント]]としてアクセスする場合並びに
「[[ログアウト]]状態の[[利用者]]」としてアクセスする場合に使います。 [SRC[>>77]]
[REFS[
- [71] [CITE@en[Service to Service Calls Using Client Credentials]] ([TIME[2015-03-05 10:43:44 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645543.aspx>
- [73] [CITE@en[Errors from Secured Resources]] ([TIME[2015-03-05 10:50:36 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645539.aspx>
- [75] [CITE@en-US[Web API Authorization Guide - Spotify Developer]] ([TIME[2015-03-05 15:59:09 +09:00]] 版) <https://developer.spotify.com/web-api/authorization-guide/>
- [77] [CITE@en[OAuth2 · reddit/reddit Wiki]] ([TIME[2015-03-05 16:36:35 +09:00]] 版) <https://github.com/reddit/reddit/wiki/OAuth2#user-content-application-only-oauth>
]REFS]
[70] [[Google]] の [[OAuth 1.0]] の拡張である [[2-legged OAuth]] を使うと、
[[Google Apps]] の (特定の[[利用者]]に限定せず)
[[ドメイン]]全体のアクセスを認めることができました。
本[[承諾型]]はこのような用途に使えるものと思われます。ただし [[Google]]
は現在 [[Google Apps]] の[[ドメイン]]全体のアクセスには
[CODE(URI)@en[[[urn:ietf:params:oauth:grant-type:jwt-bearer]]]] を使っているようです。
[TIME[2015-03-04T17:00:25.500Z]]
* [CODE(URI)@en[oauth_consumer_key]] 引数 (OAuth 1.0)
[8] [DFN[[CODE(URI)@en[[[oauth_consumer_key]]]]]] は、[[認証された要求]]で[[クライアントcredentials]]の[[識別子]]
([[consumer key]]) を表す [SRC[>>7]] [[引数]]です。
* [CODE(URI)@en[client_id]] 引数 (OAuth 2.0)
[49] [DFN[[CODE(URI)@en[[[client_id]]]]]] [[引数]]は、
[[クライアント認証]]で[[クライアント識別子]]を表します [SRC[>>34]]。
[[クライアント認証]]を行う場合、この[[引数]]は[[必須]]です [SRC[>>34]]。
[40] この[[引数]]の値は、0個以上の[[印字可能ASCII文字]]の列です [SRC[>>39]]。
[58] [[認可エンドポイント]]で[[認可符号]]や[[アクセストークン]]を取得する場合、
この[[引数]]は指定しなければ[['''なりません''']] [SRC[>>57, >>60]]。
指定されない場合や[[非妥当]]な場合、[[資源所有者]]に[[誤り]]を知らせる[['''べきです''']]
[SRC[>>59]]。
[56] [CODE(URI)@en[[[client_id]]]] [[引数]]は[[認証]]しない場合でも[[トークンエンドポイント]]への[[要求]]
[SRC[>>55]] で指定できる場合、指定しなければならない場合があります。
[[認可鯖]]は、[[トークンエンドポイント]]で適宜[[認証]]および検査しなければなりません。
;; [[トークンエンドポイント]]参照。
* [CODE(URI)@en[[[client_secret]]]] 引数 (OAuth 2.0)
[50] [DFN[[CODE(URI)@en[[[client_secret]]]]]] [[引数]]は、
[[クライアント認証]]で[[クライアント秘密]]を表します [SRC[>>34]]。
この[[引数]]は、値が[[空文字列]]なら省略できます [SRC[>>34]]。
[42] この[[引数]]の値は、0個以上の[[印字可能ASCII文字]]の列です [SRC[>>41]]。
[38] [[クライアントcredentials]]は、[[平文]]で送信しては[['''なりません''']] [SRC[>>37]]。
* [CODE(URI)@en[grant_type=client_credentials]]
[64] [[OAuth 2.0]] [[トークンエンドポイント]]の [CODE(URI)@en[[[grant_type]]]]
[[引数]]の値 [DFN[[CODE(URI)@en[[[client_credentials]]]]]] [SRC[>>41]]
は、[[クライアントcredentials]][[承諾型]]を表します。
* セキュリティー
[44] [[クライアント]]が秘密の値を保持する場合、[[ソースコード]]であれ[[バイナリ]]であれ、
それが[[公開]]されていると、 ([[暗号化]]されていたとしても原理的には)
[[クライアント]]を配布された第三者がその値を知ることができてしまいますから、
注意が必要です [SRC[>>45, >>66]]。また[[クライアント]]に埋め込まれて配布される場合、
それを [[revoke]] することも (すべての[[利用者]]が使えなくなってしまうので)
難しくなり、好ましくありません [SRC[>>66]]。
[46] [[OAuth 1.0]] では[[クライアントcredentials]]が必須なので、
秘密の値が漏れることを承知の上で[[ネイティブアプリケーション]]が配布されていたりします。
[[OAuth 2.0]] は[[クライアント型]]を設け、[[公開]]の[[クライアント]]は[[クライアント認証]]を行わないことを認めています。
[47] また、[[クライアント]]の開発者ごとに[[credentials]]を発行するのではなく、
[[クライアント]]の[[利用者]]ごとに発行することでこれを回避する場合もあります。
その場合でも、環境によっては第三者 (による[[アプリケーション]]) が[[クライアント]]の[[ストレージ]]などにアクセスして秘密の値を入手することが可能かもしれず、注意が必要です [SRC[>>45]]。
;; [51] 例えば伝統的な[[デスクトップOS]]では同じ計算機上で動作する他の[[ソフトウェア]]が[[ファイルシステム]]上の設定ファイルに容易にアクセスできるかもしれません。
[REFS[
- [45] [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.1.1>
- [66] [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-5.3.1>
]REFS]