-
Notifications
You must be signed in to change notification settings - Fork 4
/
471.txt
529 lines (412 loc) · 34.5 KB
/
471.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
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
[104] [DFN[[RUBYB[[[トークンエンドポイント]]]@en[token endpoint]]]]は、
[[クライアント]]に[[アクセストークン]]を発行する[[認可鯖]]上の[[エンドポイント]]です。
* 仕様書
[REFS[
- [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-2.3>
- [201] [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>
-- [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-3.2>
-- [52] [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>
-- [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-4.1.4>
-- [58] [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.2>
-- [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.3.2>
-- [64] [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.3.3>
-- [65] [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.2>
-- [67] [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.3>
-- [68] [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.5>
-- [71] [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-5.1>
-- [87] [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-5.2>
-- [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-6>
-- [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-9>
-- [89] [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>
- [97] [CITE[RFC Errata Report]] ([TIME[2015-02-16 00:47:02 +09:00]] 版) <http://www.rfc-editor.org/errata_search.php?rfc=6749>
- [202] [CITE@en[RFC 7521 - Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants]] ([TIME[2015-05-28 13:43:35 +09:00]] 版) <https://tools.ietf.org/html/rfc7521#section-4.1>
- [108] [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#TokenResponse>
- [109] [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#ClientAuthentication>
- [170] [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#when_to_include>
]REFS]
* OAuth 1.0 トークン要求
[8] [[クライアント]]は、[[資源所有者認可]]の後、
[DFN[[RUBYB[[[トークン要求]]]@en[token request]]]]により[[トークンcredentials]]を[[鯖]]から得ることができます。
[9] [[トークン要求]]は、[[クライアントcredentials]]と
([[トークンcredentials]]のかわりに) [[一時credentials]]を使って[[認証された要求]]です
[SRC[>>7]]。
;; [CODE(URI)@en[[[oauth_token]]]] は[[一時credentials]] の[[識別子]]となります。
[10] [[トークン要求]]は、原則として[[要求メソッド]] [CODE(HTTP)@en[[[POST]]]]
を使います [SRC[>>7]]。[[鯖]]が何らかの方法で他の[[要求メソッド]]を[[広告]]した場合には、
そちらを使うこともできます [SRC[>>7]]。
[11] [[トークン要求]]は、[[鯖]]が何らかの方法で[[広告]]した[[トークン要求]]の[[エンドポイント]]を[[要求URL]]として使います [SRC[>>7]]。
;; [105] この[[エンドポイント]]ないし [[URL]] に [[OAuth 1.0]]
は特に名前を与えていませんでしたが、 [[OAuth 2.0]] の[[トークンエンドポイント]]に相当します。
[13] [[鯖]]は、[[トークン要求]]で[[保安輸送路]]を使わなければ[['''なりません''']]
[SRC[>>7]]。
[12] [[クライアント]]は、[[資源所有者認可]]の結果得られた[[検証符号]]
(を[[資源所有者]]経由で知ったもの) を [CODE(URI)@en[[[oauth_verifier]]]]
[[引数]]に指定しなければ[['''なりません''']] [SRC[>>7]]。
[132] [[Twitter]] [[xAuth]] はそのかわりに
[CODE(URI)@en[[[x_auth_password]]]],
[CODE(URI)@en[[[x_auth_username]]]],
[CODE(URI)@en[[[x_auth_mode]]]] の指定を求めています [SRC[>>131]]。
[138] [[OAuth Session Extension]] はそのかわりに
[CODE(URI)@en[[[oauth_session_handle]]]] を指定し、また[[一時credentials]]のかわりに現行の[[アクセストークン]]を使うことで、
[[アクセストークン]]の更新ができるとしています [SRC[>>137]]。
;; [139] 後の [[OAuth 2.0]] の[[更新トークン]]に相当する機能です。
[171] [[クライアント]]は [CODE(HTTP)@en[[[oauth_body_hash]]]]
[[引数]]を指定するべき[['''ではありません''']] [SRC[>>170]]。
[REFS[
- [131] [CITE[POST oauth/access_token | Twitter Developers]] ([TIME[2015-03-05 11:38:49 +09:00]] 版) <https://dev.twitter.com/oauth/reference/post/oauth/access_token>
- [137] [CITE@en[Implementers' Draft: OAuth Session 1.0 Draft 1]] ([TIME[2008-08-22 09:10:13 +09:00]] 版) <http://oauth.googlecode.com/svn/spec/ext/session/1.0/drafts/1/spec.html#update_access_token>
]REFS]
[14] [[鯖]]は、[[トークン要求]]を受信したら次の点を確認しなければ[['''なりません''']]
[SRC[>>7]]。
[FIG(list)[
- [15] [[要求]]が妥当であるか[[検証]]する
- [16] [[資源所有者]]が[[クライアント]]に[[トークンcredentials]]を与えることを[[認可]]していることを確認する
- [17] [[一時credentials]]が[[満期]]となっておらず、使用済みでもないか確認する
- [18] [[検証符号]]が正しいものか確認する
]FIG]
[19] 確認できたなら、[[状態符号]] [CODE(HTTP)[[[200]]]]、
[[MIME型]] [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
の [[payload body]] の[[応答]]とします [SRC[>>7]]。
;; [195] [[Twitter]] の[[鯖]]は [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
を使いながらも、 [CODE(HTTP)@en[[[Content-Type:]]]] には [CODE(MIME)@en[[[text/html]]]]
を指定します。このため[[クライアント]]は [CODE(HTTP)@en[[[Content-Type:]]]]
[[ヘッダー]]を無視しなければなりません。 [TIME[2013-09-14T08:16:00.100Z]]
[20] [[payload body]] には次の[[引数]]を含めなければ[['''なりません''']] [SRC[>>7]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[CODE(URI)@en[[[oauth_token]]]]:[[トークン識別子]]
:[CODE(URI)@en[[[oauth_token_secret]]]]:[[トークン共有秘密]]
]FIG]
[136] [[OAuth Session Extension]] は更に次の[[引数]]を追加しています。
[FIG(short list)[
- [CODE(HTTP)@en[[[oauth_session_handle]]]]
- [CODE(HTTP)@en[[[oauth_authorization_expires_in]]]]
- [CODE(HTTP)@en[[[oauth_expires_in]]]]
]FIG]
[192] [[Twitter]] は次の[[引数]]を追加しています。
[FIG(short list)[
- [CODE[[[user_id]]]]
- [CODE[[[screen_name]]]]
]FIG]
[177] [[Flickr]] は次の[[引数]]を追加しています [SRC[>>176]]。
[FIG(short list)[
- [CODE(URI)@en[[[fullname]]]]
- [CODE(URI)@en[[[user_nsid]]]]
- [CODE(URI)@en[[[username]]]]
]FIG]
[169] [[はてな]]は次の[[引数]]を追加しています [SRC[>>168]]。
[FIG(short list)[
- [CODE(URI)@en[[[display_name]]]]
- [CODE(URI)@en[[[url_name]]]]
]FIG]
[184] [[Dropbox]] は [CODE[[[uid]]]] [[引数]]を追加しています [SRC[>>183]]。
[187] [[Evernote]] は [CODE[[[edam_noteStoreUrl]]]] と [CODE[[[edam_userId]]]]
と [CODE[[[edam_expires]]]] を追加しています [SRC[>>186]]。
[REFS[
- [176] [CITE@en-us[Flickr Services]] ([TIME[2015-03-06 01:25:01 +09:00]] 版) <https://www.flickr.com/services/api/auth.oauth.html>
- [168] [CITE[Consumer key を取得して OAuth 開発をはじめよう - Hatena Developer Center]] ([TIME[2015-03-05 19:09:33 +09:00]] 版) <http://developer.hatena.ne.jp/ja/documents/auth/apis/oauth/consumer>
- [183] [CITE@en[Dropbox - Core API - endpoint reference]] ([TIME[2015-03-06 09:07:10 +09:00]] 版) <https://www.dropbox.com/developers/core/docs>
- [186] [CITE@en[認証 - Evernote Developers]] ([TIME[2015-03-06 09:30:38 +09:00]] 版) <https://dev.evernote.com/intl/jp/doc/articles/authentication.php>
]REFS]
[135] [[OAuth 1.0]] 本体仕様としてはエラー時の応答については規定していません。
[[OAuth Problem Reporting Extension]] は報告方法を規定しており、
実装によってはこれに対応しています。
* OAuth 2.0 トークンエンドポイント
[35] [[認可鯖]]の[DFN[[RUBYB[[[トークンエンドポイント]]]@en[token endpoint]]]]は、
[[クライアント]]が[[認可承諾]]や[[更新トークン]]を使って[[アクセストークン]]を得るために使うものです。
[[トークンエンドポイント]]は、
[[暗示的承諾型]]以外の[[承諾型]] ([[認可符号]]、[[資源所有者合言葉credentials]]、
[[クライアントcredentials]]) で使います。 [SRC[>>34]]
** トークンエンドポイントへの要求
[36] [[クライアント]]が[[トークンエンドポイント]]の位置を知る方法は [[OAuth]]
の仕様の範囲外とされていますが、普通は[[サービス]]の[[ドキュメント]]で示されます [SRC[>>34]]。
[38] [[トークンエンドポイント]]は [[TLS]] を使わなければ[['''なりません''']] [SRC[>>34, >>89]]。
[[アクセストークン]]、[[更新トークン]]を転送する場合は [[HTTPS鯖認証]]を使わなければ[['''なりません''']] [SRC[>>89]]。
[[クライアント]]は [[RFC 6125]] により[[認可鯖]]の[[TLS証明書]]を検証し[[鯖]]の
[[identity]] を[[認証]]しなければ[['''なりません''']] [SRC[>>89]]。
[37] [[トークンエンドポイント]]の [[URL]] は
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] 形式の [[query]]
を含んでも構いません。[[素片識別子]]を含んでは[['''なりません''']]。
[[query]] が含まれる場合、[[引数]]を追加するときにはそのまま残さなければ[['''なりません''']]。
[SRC[>>34]]
[199] [[feedly]] は [CODE(HTTP)@en[[[Content-Type:]] [[application/json]]]]
を指定することで [[JSON]] [[payload body]] によって[[引数]]を指定することを認めています
[SRC[>>197]]。
[48] [[クライアント]]は、[[認可符号]]から[[アクセストークン]]を得るために[[トークンエンドポイント]]に[[要求]]を送信する場合、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[payload body]]
により次の[[引数]]を指定します [SRC[>>52]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[CODE(URI)@en[[[grant_type]]]]:[CODE(URI)@en[[[authorization_code]]]]
でなければ[['''なりません''']] [SRC[>>52]]。
:[CODE(URI)@en[[[code]]]]:受信した[[認可符号]]を指定しなければ[['''なりません''']] [SRC[>>52]]。
:[CODE(URI)@en[[[redirect_uri]]]]:[[認可エンドポイント]]への要求で
[CODE(URI)@en[[[redirect_uri]]]] [[引数]]を指定した場合は、同じ値を指定しなければ[['''なりません''']]
[SRC[>>52]]。
:[CODE(URI)@en[[[client_id]]]]:[[クライアント認証]]しない場合は指定しなければ[['''なりません''']] [SRC[>>52, >>34]]。
]FIG]
[120] [[Azure]] は [CODE(URI)@en[[[resource]]]] [[引数]]を追加しています [SRC[>>119]]。
[150] [[Salesforce]] は [CODE(URI)@en[[[code_verifier]]]], [CODE(URI)@en[[[format]]]]
を追加しています [SRC[>>149]]。
[REFS[
- [119] [CITE@en[Authorization Code Grant Flow]] ([TIME[2015-03-05 10:35:42 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645542.aspx>
- [149] [CITE[Understanding the Web Server OAuth Authentication Flow]] ([TIME[2015-02-28 04:30:54 +09:00]] 版) <https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_understanding_web_server_oauth_flow.htm>
]REFS]
[50] [[クライアント]]は、[[資源所有者]]の [[credentials]] から[[アクセストークン]]を得るため
([[資源所有者合言葉credentials]]フロー) に[[トークンエンドポイント]]に[[要求]]を送信する場合、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[payload body]]
により次の[[引数]]を指定します [SRC[>>61]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[CODE(URI)@en[[[grant_type]]]]:[CODE(URI)@en[[[password]]]]
でなければ[['''なりません''']] [SRC[>>61]]。
:[CODE(URI)@en[[[username]]]]:[[資源所有者]]の[[利用者名]]を指定しなければ[['''なりません''']] [SRC[>>61]]。
:[CODE(URI)@en[[[password]]]]:[[資源所有者]]の[[合言葉]]を指定しなければ[['''なりません''']]
[SRC[>>61]]。
:[CODE(URI)@en[[[scope]]]]:アクセス要求の[[適用範囲]]を指定できます [SRC[>>61]]。
]FIG]
[66] [[クライアント]]は、[[クライアントcredentials]] から[[アクセストークン]]を得るため
([[クライアントcredentials]]フロー) に[[トークンエンドポイント]]に[[要求]]を送信する場合、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[payload body]]
により次の[[引数]]を指定します [SRC[>>65]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[CODE(URI)@en[[[grant_type]]]]:[CODE(URI)@en[[[client_credentials]]]]
でなければ[['''なりません''']] [SRC[>>65]]。
:[CODE(URI)@en[[[scope]]]]:アクセス要求の[[適用範囲]]を指定できます [SRC[>>65]]。
]FIG]
[125] [[Azure]] は [CODE(URI)@en[[[resource]]]] [[引数]]を追加しています [SRC[>>124]]。
[146] [[reddit]] は場合によって [CODE(URI)@en[[[grant_type]]=[[https://oauth.reddit.com/grants/installed_client]]]]
を使います。また [CODE(URI)@en[[[device_id]]]] [[引数]]を追加しています。 [SRC[>>145]]
[REFS[
- [124] [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>
- [145] [CITE@en[OAuth2 · reddit/reddit Wiki]] ([TIME[2015-03-05 16:39:22 +09:00]] 版) <https://github.com/reddit/reddit/wiki/OAuth2#user-content-application-only-oauth>
]REFS]
[2] [[クライアント]]は、[[更新トークン]] から[[アクセストークン]]を得るために[[トークンエンドポイント]]に[[要求]]を送信する場合、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[payload body]]
により次の[[引数]]を指定します [SRC[>>1]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[CODE(URI)@en[[[grant_type]]]]:[CODE(URI)@en[[[refresh_token]]]]
でなければ[['''なりません''']] [SRC[>>1]]。
:[CODE(URI)@en[[[refresh_token]]]]:[[クライアント]]に発行されている[[更新トークン]]を指定しなければ[['''なりません''']] [SRC[>>1]]。
:[CODE(URI)@en[[[scope]]]]:アクセス要求の[[適用範囲]]を指定できます [SRC[>>1]]。
元々[[資源所有者]]に[[承諾]]された[[適用範囲]]以外を指定しては[['''なりません''']] [SRC[>>1]]。
省略すると、元々[[資源所有者]]に[[承諾]]された[[適用範囲]]を表します [SRC[>>1]]。
]FIG]
[122] [[Azure]] は [CODE(URI)@en[[[resource]]]] [[引数]]を追加しています [SRC[>>119]]。
[158] [[Salesfoce]] は [CODE(URI)@en[[[format]]]] [[引数]]を追加しています [SRC[>>157]]。
[203] [[assertion]] を使う場合は、 [CODE(URI)@en[[[grant_type]]]]
[[引数]]を [[assertion]] の種別を表す[[絶対URL]]、 [CODE(URI)@en[[[assertion]]]]
[[引数]]を [[assertion]] の値とします。 [CODE(URI)@en[[[scope]]]]
[[引数]]も指定できます。 [SRC[>>202]]
[EG[
[70] 例えば [[SAML 2.0]] が拡張の[[承諾型]]を規定しています。
]EG]
[EG[
[113] 例えば [[JWT]] を使う場合、
[CODE(URI)@en[[[grant_type]]=[[urn:ietf:params:oauth:grant-type:jwt-bearer]]]]
と [CODE(URI)@en[[[assertion]]]] [[引数]]を指定します。
[114] [[Google]] がこれを実装している [SRC[>>115]] ようです。
[REFS[
- [115] [CITE@ja[Using OAuth 2.0 for Server to Server Applications - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2015-02-04 03:07:26 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth2ServiceAccount>
]REFS]
]EG]
[69] [[クライアント]]は、拡張の[[承諾型]]の規定に従い[[トークンエンドポイント]]に[[要求]]を送信する場合、
[CODE(URI)@en[[[grant_type]]]] [[引数]]に[[絶対URL]]を指定し、
必要に応じて追加の[[引数]]も指定します [SRC[>>68]]。
[EG[
[116] [[Google]] は [[OAuth 1.0]] から [[OAuth 2.0]] への移行のために
[CODE(URI)@en[[[grant_type]]=[[urn:ietf:params:oauth:grant-type:migration:oauth1]]]]
を提供していました。 [[OAuth 2.0]] [[クライアント認証]]、 [[OAuth 1.0]] による
[[HTTP認証]]、省略可能な [CODE(URI)@en[[[scope]]]] [[引数]]を指定することで、
[[更新トークン]]を得ることができるものです。
;; [CODE(URI)@en[[[urn:ietf:params:oauth:grant-type:migration:oauth1]]]] 参照。
]EG]
[EG[
[165] [[Facebook]] の [CODE(URI)@en[[[grant_type]]=[[fb_exchange_token]]]]
は [CODE(URI)@en[[[fb_exchange_token]]]] [[引数]]を使っています [SRC[>>164]]。
]EG]
;; [123] [[Azure]] は [CODE(URI)@en[[[grant_type]]]] という名前で
[CODE(URI)@en[[[response_type]]]] [[引数]]に相当するものを指定させています [SRC[>>119, >>124]]。
[41] [[要求]]の[[引数]]は、複数指定しては[['''なりません''']] [SRC[>>34]]。
[160] [[SurveyMonkey]] は [[payload body]] ではなく [[URL query]] に
[CODE(URI)@en[[[api_key]]]] [[引数]]を指定することを求めています [SRC[>>159]]。
[189] [[GitLab]] は[[要求]]の [[payload body]] の [[JSON]] によって[[引数]]を指定させています [SRC[>>188]]。
[REFS[
- [159] [CITE@en[SurveyMonkey - Guide OAuth]] ([TIME[2015-03-05 17:23:37 +09:00]] 版) <https://developer.surveymonkey.com/mashery/guide_oauth>
- [161] [CITE[Connecting]] ([TIME[2015-03-05 17:39:49 +09:00]] 版) <https://developer.foursquare.com/overview/auth>
- [164] [CITE@ja[Access Tokens]] ([TIME[2015-03-05 18:03:06 +09:00]] 版) <https://developers.facebook.com/docs/facebook-login/access-tokens>
- [188] [CITE@en[gitlabhq/oauth2.md at master · gitlabhq/gitlabhq]] ([TIME[2015-03-06 10:46:37 +09:00]] 版) <https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/oauth2.md>
]REFS]
[39] [[クライアント]]は[[トークンエンドポイント]]への[[要求]]で [CODE(HTTP)@en[[[POST]]]]
[[要求メソッド]]を使わなければ[['''なりません''']] [SRC[>>34]]。
[162] [[Facebook]] [SRC[>>164]] や [[fouresquare]] [SRC[>>161]]
は [CODE(HTTP)@en[[[GET]]]] を使っているようです。
** クライアント認証
[22] [[クライアント]]は、[[トークンエンドポイント]]や
[[revokeエンドポイント]]への[[要求]]で、
[CODE(URI)@en[[[client_id]]]] [[引数]]を指定できます。また、
場合によっては[[認証]]に必要な情報を指定しなければなりません。
[23] [[認可サーバー]]は、[[トークンエンドポイント]]や[[revokeエンドポイント]]で、
場合によっては[[クライアント認証]]を行わなければなりません。
[24] 詳細は、[[OAuth 2.0クライアント認証]]を参照。
;; [25] [[TLSクライアント認証]]とは関係ありません。
** トークンエンドポイントの処理
[83] [[認可鯖]]は、認識できない[[引数]]を無視しなければ[['''なりません''']] [SRC[>>34]]。
[40] [[要求]]の[[引数]]に値が含まれなければ、指定されなかったものと扱わなければ[['''なりません''']] [SRC[>>34]]。
;; [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] で [CODE[[[=]]]]
が含まれない場合を指しているのでしょうか? [[空文字列]]が指定された場合と区別する必要があるということでしょうか??
[54] [[認可鯖]]は、[[認可符号]]から[[アクセストークン]]の発行を求められている場合、
[[認可符号]]が妥当なものであることを確認しなければ[['''なりません''']] [SRC[>>52]]。
[[認可符号]]は1回しか使えません。
[100] 攻撃者は大量の[[要求]]で[[クライアント]]に適当な[[認可符号]]を与え、[[認可鯖]]にアクセスさせることで、
間接的に[[認可鯖]]の[[HTTP接続]]を枯渇させる [[DoS攻撃]]を試みるかもしれません。
[[認可鯖]]には攻撃者の情報がほとんど届かず、対策が難しい攻撃です。
[[認可鯖]]は不適切な[[認可符号]]があまりに多い[[クライアント]]には[[誤り]]応答を返すべきかもしれません [SRC[>>99]]。
[REFS[
- [99] [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.12>
]REFS]
[53] [[認可鯖]]は、[[認可符号]]から[[アクセストークン]]の発行を求められている場合、
[[クライアント型]]が[[機密]]の[[クライアント]]に対するものであるか、
[[クライアント型]]が[[公開]]の[[クライアント]]に対するもので[[認可符号]]の発行先と
[CODE(URI)@en[[[client_id]]]] が合致していることを確認しなくては[['''なりません''']] [SRC[>>52, >>89]]。
[102] 攻撃対象の[[クライアント]]がいわゆる[[OAuthログイン]]を実装している場合において、攻撃者の有する[[クライアント]]に攻撃対象の[[資源所有者]]を誘導して[[認可符号]]を取得し、その[[認可符号]]を攻撃対象の[[クライアント]]に与えることで、攻撃者が攻撃対象[[クライアント]]における攻撃対象[[資源所有者]]になりすまして[[ログイン]]できてしまいます [SRC[>>101]]。
[[公開]]の[[クライアント]]に関してこれを防ぐことはできません。
[REFS[
- [101] [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]
[54] [[認可鯖]]は、[[認可符号]]から[[アクセストークン]]の発行を求められている場合、
[[認可エンドポイント]]へのアクセス時に [CODE(URI)@en[[[redirect_uri]]]]
[[引数]]が指定されていたなら本要求にも [CODE(URI)@en[[[redirect_uri]]]]
[[引数]]が含まれており、両者の値が一致することを確認しなければ[['''なりません''']]
[SRC[>>52, >>89]]。
[62] [[認可鯖]]は、[[資源所有者]]の [[credentials]] から[[アクセストークン]]の発行を求められている場合、
指定された [[credentials]] を検証しなければ[['''なりません''']] [SRC[>>52]]。
[3] [[認可鯖]]は、[[更新トークン]]から[[アクセストークン]]の発行を求められている場合、
指定された[[更新トークン]]を検証しなければ[['''なりません''']] [SRC[>>1]]。
[[クライアント認証]]可能であれば、正しい[[クライアント]]か検証しなければ[['''なりません''']]
[SRC[>>89]]。
[63] [[認可鯖]]は、回数制限や警告などにより、[[資源所有者合言葉credentials]]
の[[総当たり攻撃]]から[[エンドポイント]]を保護しなければ[['''なりません''']] [SRC[>>52]]。
[95] [[認可鯖]]は [[CSRF]] 対策が必要です。[[資源所有者]]の [[credentials]]
を第三者に漏らしてしまう形の攻撃は難しそうですが、[[認可鯖]] (や間接的に[[クライアント]])
に対する [[DoS攻撃]]や、 [[CSRF]] を引き起こされた被害者たる
[[Webブラウザー]]の利用者への嫌がらせには使えるかもしれません。
;; [96] その性質上、[[CSRF]] 対策用のトークンを指定させるような方法は使えません。
[CODE(HTTP)@en[[[Origin:]]]] [[ヘッダー]]の値と[[クライアント]]の登録情報を比較して不適切な[[要求]]を検出するのがよいでしょうか。
** トークンエンドポイントの応答
[56] [[認可鯖]]は、[[アクセストークン]]の発行を求められている場合、
要求が妥当であり[[認可]]されたなら、[[アクセストークン]]を発行します
[SRC[>>55, >>64, >>67, >>68, >>1]]。
[4] [[認可符号]]や[[資源所有者合言葉credentials]]、拡張の[[承諾型]]では、
[[更新トークン]]も発行することもできます [SRC[>>55, >>64, >>68]]。
ただし[[クライアント認証]]していない場合には発行するべきではないかもしれません [SRC[>>89]]。
[5] [[クライアントcredentials]]では、
[[更新トークン]]を発行する[['''べきではありません''']] [SRC[>>67]]。
[6] [[更新トークン]]から[[アクセストークン]]を求めている場合には、
新しい[[更新トークン]]を発行しても構いません。その[[適用範囲]]
([[scope]]) は元の[[更新トークン]]と同じでなければ[['''なりません''']]。
その場合には[[認可鯖]]は古い[[更新トークン]]を取り消し ([[revoke]])
して構いませんし、[[クライアント]]は古い[[更新トークン]]を破棄しなければ[['''なりません''']]。
[SRC[>>1]]
[72] その場合には、 [CODE(HTTP)[[[200]]]] [[応答]]で次の[[引数]]を
[[JSON]] ([CODE(MIME)@en[[[application/json]]]]) [[payload body]] の
[[JSONオブジェクト]]の名前と値 ([[文字列]]なら [[JSON文字列]]、
[[数値]]なら [[JSON数値]]) に含めます [SRC[>>71]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([[JSONオブジェクト]])
]FIGCAPTION]
:[73] [CODE(HTTP)@en[[[access_token]]]]:[[認可鯖]]が発行した[[アクセストークン]]を指定しなければ[['''なりません''']] [SRC[>>71]]。
:[74] [CODE(HTTP)@en[[[token_type]]]]:発行した[[トークン]]の種類を指定しなければ[['''なりません''']]
[SRC[>>71]]。
:[75] [CODE(HTTP)@en[[[expires_in]]]]:[[アクセストークン]]の[[寿命]]を[[秒]]単位で指定する[['''べきです''']] [SRC[>>71]]。
:[76] [CODE(HTTP)@en[[[refresh_token]]]]:同じ[[認可承諾]]を使って新しい[[アクセストークン]]を得られる[[更新トークン]]を指定できます [SRC[>>71]]。
:[77] [CODE(HTTP)@en[[[scope]]]]:[[クライアント]]が要求した[[適用範囲]]と[[アクセストークン]]の[[適用範囲]]が異なるなら、指定しなければ[['''なりません''']]。同じ場合も指定できます。 [SRC[>>71]]
:[107] [CODE(HTTP)@en[[[id_token]]]]:[[OpenID Connect]] の場合には指定しなければ[['''なりません''']] [SRC[>>108]]。
]FIG]
;; [78] どれが文字列でどれが数値かは明確ではありませんが、
[CODE(HTTP)@en[[[expires_in]]]] は[[数値]]、それ以外は[[文字列]]と思われます。
[106] [[アクセストークン型]]によっては、更に追加の[[引数]]を指定する必要があるかもしれません。
;; [[アクセストークン型]]を参照。
[117] [CODE(URI)@en[[[grant_type]]=[[urn:ietf:params:oauth:grant-type:migration:oauth1]]]]
では、 [CODE(URI)@en[[[refresh_token]]]] ([[更新トークン]]) のみが返されることになっていました。
[121] [[Azure]] は [CODE(URI)@en[[[resource]]]] [[引数]]と
[CODE(URI)@en[[[expires_on]]]] [[引数]]を追加しています [SRC[>>119]]。
[134] [[ヤマレコ]]は [CODE(URI)@en[[[token_type]]]] [[引数]]を指定せず、
成功時でも [CODE[[[error]]]] [[引数]]と [CODE[[[error_message]]]]
[[引数]] (独自) を指定するようです [SRC[>>133]]。
[148] [[Instagram]] は [CODE(URI)@en[[[token_type]]]] [[引数]]を指定せず、
[CODE(URI)@en[[[user]]]] [[引数]] (独自) を指定するようです [SRC[>>147]]。
;; [CODE(URI)@en[[[user]]]] の値は [[JSONオブジェクト]]です。
[173] [[Bitly]] は [CODE@en[[[apiKey]]]] [[引数]] (独自) を指定するようです。
ただし非推奨で削除予定とあります。 [SRC[>>172]] [TIME[2015-03-05T16:02:49.500Z]]
[179] [[Heroku]] は [CODE@en[[[user_id]]]]、[CODE[[[session_nonce]]]]
を指定するようです [SRC[>>178]]。
[182] [[Yahoo!]] は [CODE@en[[[xoauth_yahoo_guid]]]] を指定するようです [SRC[>>181]]。
[198] [[feedly]] は [CODE[[[plan]]]] を指定するようです [SRC[>>197]]。
[143] [[foursquare]] など [SRC[>>161, >>163, >>142, >>172]] は [CODE(URI)@en[[[token_type]]]] [[引数]]を指定しないようです。
[194] [[Facebook]] は [CODE(URI)@en[[[token_type]]]] [[引数]]を指定しません。
[CODE(URI)@en[[[expires_in]]]] ではなく [CODE(URI)@en[[[expires]]]]
[[引数]]に [[time_t]] 値を指定するようです。
[152] [[Salesforce]] は [CODE(URI)@en[[[token_type]]]] [[引数]]を指定しないようです。
独自の [CODE(URI)@en[[[id]]]], [CODE(URI)@en[[[instance_url]]]],
[CODE(URI)@en[[[issued_at]]]], [CODE(URI)@en[[[signature]]]] を指定するようです。 [SRC[>>149, >>156, >>157]]
[151] [[Salesforce]] は[[要求]]で [CODE(URI)@en[[[format]]]] [[引数]]を指定した場合に[[応答]]が他の[[MIME型]]になるようです [SRC[>>149, >>157]]。
[167] [[GitHub]] は[[要求]]で [CODE(HTTP)@en[[[Accept:]]]] を指定した場合に[[応答]]が他の
[[MIME型]]になるようです。既定値は [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
になっているようです。 [SRC[>>166]]
[193] [[Facebook]] は[[応答]]に [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
を使うようです。ただし [CODE(HTTP)@en[[[Content-Type:]]]] はなぜか
[CODE[[[text/plain]]; [[charset]]=[[UTF-8]]]] になります。 [TIME[2015-03-10T15:02:45.900Z]]
[42] [[応答]]の[[引数]]は、複数指定しては[['''なりません''']] [SRC[>>34]]。
[79] 更に、 [CODE(HTTP)@en[[[Cache-Control:]] [[no-store]]]] と
[CODE(HTTP)@en[[[Pragma:]] [[no-cache]]]] を含めなければ[['''なりません''']] [SRC[>>71]]。
[80] [[クライアント]]は、認識できない名前の[[引数]]を無視しなければ[['''なりません''']]
[SRC[>>71]]。
[56] [[認可鯖]]は、[[アクセストークン]]の発行を求められている場合、
[[クライアント認証]]に失敗したか要求が非妥当であったなら、
誤り応答を返します [SRC[>>55, >>64, >>67, >>68, >>1]]。
[88] その場合には、 [CODE(HTTP)[[[400]]]] [[応答]]で次の[[引数]]を
[[JSON]] ([CODE(MIME)@en[[[application/json]]]]) [[payload body]] の
[[JSONオブジェクト]]の名前と値 ([[文字列]]なら [[JSON文字列]]、
[[数値]]なら [[JSON数値]]) に含めます [SRC[>>87]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([[JSONオブジェクト]])
]FIGCAPTION]
:[84] [CODE(URI)@en[[[error]]]]:[[誤り符号]]を指定しなければ[['''なりません''']] [SRC[>>87]]。
:[85] [CODE(URI)@en[[[error_description]]]]:[[人間可読]]な[[誤り]]の説明を指定して構いません
[SRC[>>87]]。
:[86] [CODE(URI)@en[[[error_uri]]]]:[[人間可読]]な[[誤り]]の説明を含む[[Webページ]]の [[URL]]
を指定して構いません [SRC[>>87]]。
]FIG]
;; [126] [[誤り符号]]によっては、他の [[HTTP]] [[状態符号]]を使うこともあるようです。
[127] [[Azure]] は [CODE(URI)@en[[[timestamp]]]]、[CODE(URI)@en[[[trace_id]]]]、
[CODE@en[[[correlation_id]]]]、[CODE@en[[[error_codes]]]] を追加しています [SRC[>>128]]。
[REFS[
- [128] [CITE@en[Token Issuance Endpoint Errors]] ([TIME[2015-03-05 10:47:08 +09:00]] 版) <https://msdn.microsoft.com/en-us/library/azure/dn645548.aspx>
- [156] [CITE[Understanding the Username-Password OAuth Authentication Flow]] ([TIME[2015-02-28 04:30:54 +09:00]] 版) <https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_understanding_username_password_oauth_flow.htm>
- [157] [CITE[Understanding the OAuth Refresh Token Process]] ([TIME[2015-02-28 04:30:54 +09:00]] 版) <https://www.salesforce.com/us/developer/docs/api_rest/Content/intro_understanding_refresh_token_oauth.htm>
- [178] [CITE@en[OAuth | Heroku Dev Center]] ([TIME[2015-03-06 08:03:38 +09:00]] 版) <https://devcenter.heroku.com/articles/oauth#oauth-flow-response>
- [197] [CITE@en[Authentication | feedly Cloud API]] ([TIME[2015-01-23 08:10:58 +09:00]] 版) <https://developer.feedly.com/v3/auth/>
]REFS]
[51] [CODE(URI)@en[[[error]]]] が [CODE@en[[[invalid_client]]]] の場合には、
[CODE(HTTP)[[[401]]]] [[応答]]とすることもできます。
[[クライアント]]が [CODE(HTTP)@en[[[Authorization:]]]] [[ヘッダー]]で[[認証]]を試みた場合には、
[CODE(HTTP)[[[401]]]] [[応答]]と [CODE(HTTP)@en[[[WWW-Authenticate:]]]]
[[ヘッダー]] ([[auth-scheme]] は[[要求]]で指定されたもの) を使って[[応答]]しなければ[['''なりません''']] [SRC[>>87]]。
[196] [CITE@en[draft-richer-oauth-xml-01 - Alternate Encoding for OAuth 2 Token Responses]]
([TIME[2015-01-18 17:52:17 +09:00]] 版)
<https://tools.ietf.org/html/draft-richer-oauth-xml-01>