-
Notifications
You must be signed in to change notification settings - Fork 4
/
547.txt
204 lines (151 loc) · 12.8 KB
/
547.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
[2] [DFN[[RUBYB[revoke エンドポイント]@en[revocation endpoint]]]]は、[[アクセストークン]]や[[更新トークン]]を取り消し ([[revoke]]) するための[[エンドポイント]]です。
* 仕様書
[REFS[
- [1] '''[CITE@en[RFC 7009 - OAuth 2.0 Token Revocation]] ([TIME[2014-12-21 18:10:21 +09:00]] 版) <http://tools.ietf.org/html/rfc7009>'''
- [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>
- [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-5.2>
]REFS]
* 意味
[3] [RUBYB[取り消し要求]@en[revocation request]]は、
[[クライアント]]が自身の保持する[[アクセストークン]]や[[更新トークン]]を無効化することを[[認可鯖]]に求めるものです。 [SRC[>>1]]
[41] [[認可鯖]]は、求められた[[トークン]]を無効にすると共に、
関係する他の[[トークン]]や、セッションデータ等関係するデータを消去できます [SRC[>>1]]。
[6] 実装は、[[更新トークン]]の [[revoke]] に対応しなければ[['''なりません''']] [SRC[>>1]]。
[7] 実装は、[[アクセストークン]]の [[revoke]] に対応する[['''べき''']]です [SRC[>>1]]。
;; [8] しかしながら、実装が [[revoke]] に対応すること自体は必須とはなっていません。
[[OAuth]] 本体に対応していても、 [[revoke]] には対応していない可能性があります。
また[[更新トークン]]を使わない実装は[[更新トークン]]の [[revoke]]
にも対応していない (できない) かもしれません。
;; [39] [[更新トークン]]の [[revoke]] により[[アクセストークン]]が [[revoke]]
されることは保証されませんし、されたかどうか直接知ることもできません。
[[クライアント]]は確実に [[revoke]] したければ両方を明示的に [[revoke]]
する必要があります。
[EG[
[4] [[OAuth]] はしばしば [[Webアプリケーション]]の[[ログイン]]の仕組みとして使われます。
そのような[[Webアプリケーション]] ([[クライアント]]) は、
[[末端利用者]] ([[資源所有者]]) が[[ログアウト]]したり[[アンインストール]]したりした時に、
[[トークン]]を [[revoke]] することができます。 [SRC[>>1]]
]EG]
[5] [[トークン]]を [[revoke]] することで、[[ログアウト]]等の後[[末端利用者]]が気づかないまま[[トークン]]が残ってしまうことを防げますし、
乱用されることも防げます。 [SRC[>>1]]
;; [42] [[クライアント]]が [[revoke]] するのは任意であり、[[末端利用者]]は [[revoke]]
したかどうか直接知ることができないので、[[クライアント]]が悪意を持っている場合の対策にはならず、
せいぜい流出した時の被害を抑えるくらいの役目しか果たしませんが...
[43] [[認可鯖]]が[[末端利用者]]に対して[[認可承諾]]の一覧を提示している場合には、
そこからも消去されるでしょう。 [SRC[>>1]] 使わなくなった[[クライアント]]が一覧に残り続けるよりは良さそうです。
[24] [[クライアント]]は、 [[revokeエンドポイント]]が [CODE(HTTP)[[[200]]]]
を返した後その[[トークン]]を使おうと試みてはなりません [SRC[>>1]]。
[26] なお、[[トークン]]はこの仕組み以外でも無効になることがあります。
[[クライアント]]は、いつでも[[トークン]]が無効にされる可能性を考慮しておかなければなりません
[SRC[>>1]]。例えば[[資源所有者]]が [[revoke]] するかもしれませんし、
[[認可鯖]]が自身の判断で無効化するかもしれません。
* クライアントの要求
[9] [[クライアント]]は、 [CODE(HTTP)@en[[[POST]]]] [[要求]]を使います [SRC[>>1]]。
[[JSONP]] を使う場合には [CODE(HTTP)@en[[[GET]]]] [[要求]]でも構いません [SRC[>>1]]。
;; [46] [[Google]] は [CODE(HTTP)@en[[[GET]]]] を使っています [SRC[>>45]]。
[[JSONP]] では無いようです。 [[RFC]] 以前からある独自の [[API]] かもしれません。
[REFS[
- [45] [CITE@ja[Using OAuth 2.0 for Web Server Applications - Google Accounts Authentication and Authorization — Google Developers]] ([TIME[2014-12-05 11:52:25 +09:00]] 版) <https://developers.google.com/accounts/docs/OAuth2WebServer#tokenrevoke>
]REFS]
[13] [[クライアント]]が [[revokeエンドポイント]]の [[URL]]
を得る方法は、 [[OAuth]] 仕様の範囲外です。[[鯖]]のドキュメントから調べても構いませんし、
自動的な[[発見]]の仕組みを使っても構いません。いずれにせよ信頼できる情報源に拠る必要があります。
[SRC[>>1]]
[14] [[revokeエンドポイント]]の [[URL]] は、 [[HTTPS]] でなければ[['''なりません''']]。
[[認可鯖]]は [[TLS]] を使わなければ[['''なりません''']]。
[[クライアント]]は [[HTTPS]] の [[URL]] であることを[RUBYB[検証]@en[verify]]しなければ[['''なりません''']]。
[[クライアント]]は偽の[[revokeエンドポイント]]を検出するため、[[証明書]]の検証などにより[[認証]]しなければ[['''なりません''']]。
[SRC[>>1]]
[15] [[revokeエンドポイント]]が素の [[HTTP]] でも利用できるなら、
そちらでの [[revoke]] にも対応する[['''べき''']]ですが、
これを [[revokeエンドポイント]]の [[URL]] として出版しては[['''なりません''']]。 [SRC[>>1]]
;; [16] こうすることにより、誤って [[HTTP]] で送信してしまったトークンも [[revoke]]
できます [SRC[>>1]]。
[11] [[revokeエンドポイント]]の [[URL]] は、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
形式の [[query]] を含んでいても構いません [SRC[>>1, >>10]]。
[12] [[URL]] に[[引数]]を追加する時は、元の [[query]] を残さなければ[['''なりません''']]
[SRC[>>1, >>10]]。
[17] [[クライアント]]は [CODE(HTTP)@en[[[POST]]]] [[要求]]の [[payload body]] または
[[JSONP]] [CODE(HTTP)@en[[[GET]]]] [[要求]]の [[URL query]] に
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
形式で次の[[引数]]を指定します [SRC[>>1]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] または [[URL query]] ([CODE(MIME)@en[[[application/x-www-form-urlencoded]]]])
]FIGCAPTION]
:[18] [CODE(URI)@en[[[token]]]]:[[revoke]] したい[[トークン]]を指定しなければ[['''なりません''']] [SRC[>>1]]。
:[19] [CODE(URI)@en[[[token_type_hint]]]]:[CODE(URI)@en[[[token]]]] の種別のヒントです。
[[クライアント]]はこれを指定しても構いません。 [SRC[>>1]]
:[33] [CODE(URI)@en[[[callback]]]]:[[JSONP]] の場合に、 [[JavaScript]] [[関数]]の[[修飾名]]を指定します [SRC[>>1]]。
]FIG]
[20] [[クライアント]]は、[[クライアント認証]] (または認証できない場合には
[CODE(URI)@en[[[client_id]]]] [[引数]]) も含めます [SRC[>>1]]。
* 認可鯖の処理
[32] [[認可鯖]]は、 [[利用者エージェントベースのアプリケーション]]で使われるかもしれない場合には、
[[CORS]] に対応して構いません [SRC[>>1]]。
;; [44] 特別な [[CSRF]] 対策は必要無さそうです。
[21] [[認可鯖]]は、まず ([[機密]]の[[クライアント]]なら)
[[クライアントcredentials]]を[RUBYB[検証]@en[validate]]します [SRC[>>1]]。
;; [[クライアント認証]]参照。[[RFC]] には明記されていませんが、
整合性を考えると[[機密]]でなくても[[クライアントcredentials]]が発行されている場合には検証するべきと思われます。
[22] [[認可鯖]]は、次に[[トークン]]が当該[[クライアント]]に発行されたものか[RUBYB[検証]@en[verify]]します。
失敗した場合は、エラーを返して終わります。 [SRC[>>1]]
[37] [[RFC]] には明記されていませんが、[[引数]]の重複や欠落などがあれば、
エラーを返して終わるべきと思われます。
[23] [[認可鯖]]は、その後[[トークン]]を非妥当化します。非妥当化は直ちに行われ、
以後[[トークン]]は使えなくなります。実際には伝播遅延があるかもしれませんが、
できるだけ短期間で反映されるようにするべきです。 [SRC[>>1]]
[29] [CODE(URI)@en[[[token_type_hint]]]] の指定は、あまり意味がありません。
;; [CODE(URI)@en[[[token_type_hint]]]] 参照。
[25] [[認可鯖]]は、 [[revoke]] に関する方針次第で、
関連するトークンや元になった[[認可承諾]]をも [[revoke]]
して構いません。 [[更新トークン]]の [[revoke]] においては、
[[認可鯖]]が[[アクセストークン]]の [[revoke]]
にも対応しているなら、同じ[[認可承諾]]に基づくすべての[[アクセストークン]]をも
[[revoke]] する[['''べき''']]です。
[[アクセストークン]]の [[revoke]] においては、
対応する[[更新トークン]]も [[revoke]] して構いません。 [SRC[>>1]]
[27] [[認可鯖]]は、 [[revoke]] に成功したい場合や、
非妥当な[[トークン]]が指定されていた場合は、 [CODE(HTTP)[[[200]]]]
[[応答]]を返します [SRC[>>1]]。
[88] [[認可鯖]]は、誤りの場合には、 [CODE(HTTP)[[[400]]]] [[応答]]で次の[[引数]]を
[[JSON]] ([CODE(MIME)@en[[[application/json]]]]) [[payload body]] の
[[JSONオブジェクト]]の名前と値 ([[文字列]]なら [[JSON文字列]]、
[[数値]]なら [[JSON数値]]) に含めます [SRC[>>1, >>30]]。
[FIG(list members)[
[FIGCAPTION[
[[payload body]] ([[JSONオブジェクト]])
]FIGCAPTION]
:[84] [CODE(URI)@en[[[error]]]]:[[誤り符号]]を指定しなければ[['''なりません''']] [SRC[>>30]]。
:[85] [CODE(URI)@en[[[error_description]]]]:[[人間可読]]な[[誤り]]の説明を指定して構いません
[SRC[>>30]]。
:[86] [CODE(URI)@en[[[error_uri]]]]:[[人間可読]]な[[誤り]]の説明を含む[[Webページ]]の [[URL]]
を指定して構いません [SRC[>>30]]。
]FIG]
[40] [[認可鯖]]は、 [[DoS攻撃]]に注意しなければ[['''なりません''']] [SRC[>>1]]。
[28] [[クライアント]]は、 [CODE(HTTP)[[[200]]]] [[応答]]の [[payload body]] を無視します
[SRC[>>1]]。
[31] [[クライアント]]は、 [CODE(HTTP)[[[503]]]] [[応答]]を受信したらトークンはまだ有効と判断しなければならず、
適当な間を置いて再試行して構いません。[[鯖]]は [CODE(HTTP)@en[[[Retry-After:]]]]
で利用できないと思われる期間を示すことができます。 [SRC[>>1]]
[34] [[クライアント]]は、 [[JSONP]] の場合不正な [[revokeエンドポイント]]が不正なコードを注入する危険性があることに注意するべきです [SRC[>>1]]。
;; [35] そんなレベルで[[認可鯖]]が信用できない状況では [[OAuth]] 関連の処理がすべて危険そうですが...
* 歴史
[49] [[OAuth 1.0]] には [[revoke]] [[API]] はありませんでした。
[47] [[Google]] は [[OAuth 1.0]] [[アクセストークン]]について、
[[AuthSub]] の [[revokeエンドポイント]]を使って [[revoke]] できる [SRC[>>48]]
としていました。
[51] [[Twitter]] は [[OAuth 2.0]] 向けに独自仕様の [[revokeエンドポイント]]を実装しています
[SRC[>>50]]。
[REFS[
- [48] [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#RevokeToken>
- [50] [CITE[POST oauth2/invalidate_token | Twitter Developers]] ([TIME[2015-03-05 11:07:26 +09:00]] 版) <https://dev.twitter.com/oauth/reference/post/oauth2/invalidate/token>
]REFS]
* メモ
[36] [[RFC 7009]] は [[OAuth]] 関連仕様の中でも特に品質が低いようです。
他の [[RFC]] を参照している箇所は章番号だけでどの規定が引用されているのか自明ではなかったりしますし、
[[事実の文]]による状況の説明ばかりで[[助動詞]]が含まれる規定の文は少なく、
前世紀レベルです。 [[JSONP]] に関する部分に至っては規定がほとんどなく例示に頼っています。
[38] [[RFC]] は未だに [[JSONP]] を考慮しているようですが、出版された2013年の時点ではぎりぎりまだ必要があったかもしれません。
現在では最早何の意味もなく、危険なだけなので [[CORS]] を使うべきでしょう。