/
596.txt
233 lines (178 loc) · 17.8 KB
/
596.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
[2] [[OAuth 2.0]] の[DFN[[RUBYB[[[クライアント認証]]]@en[client authentication]]]]は、[[クライアント]] ([[Web API]]
にアクセスする外部サービス) に関して[[認可サーバー]]が[[認証]]するものです。
* 仕様書
[REFS[
- [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>
-- [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>
-- [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>
-- [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>
- [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>
- [4] [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.2>
]REFS]
* 文脈
[43] [[クライアント型]]が[[機密]]の[[クライアント]]と、
[[クライアントcredentials]]を発行された[[クライアント]]は、
[[トークンエンドポイント]]への[[要求]]で[[クライアント認証]]を行わなければ[['''なりません''']]
[SRC[>>34, >>52, >>61, >>65, >>1]]。
ただし[[ネイティブアプリケーション]]は、
[[認可符号]]フローにおいて[[クライアント]]の [[credentials]]
を送信する[['''べきではありません''']] [SRC[>>21]]。
[49] [[クライアント型]]が[[公開]]の[[クライアント]]は、(以上に該当しなくても)
[[トークンエンドポイント]]への[[要求]]で自身を識別する
[CODE(URI)@en[[[client_id]]]] [[引数]]を使っても構いません [SRC[>>34, >>97]]。
;; この場合は [[credentials]] は指定しないので、[[クライアント認証]]は行われません。
[98] なおこの[[クライアント認証]]は、[[トークンエンドポイント]]の他、
[[revokeエンドポイント]]でも使われます。
* 処理
[82] [[認可鯖]]は、[[クライアント型]]が[[機密]]の[[クライアント]]や[[クライアントcredentials]]
を発行した[[クライアント]]に関しては、
[[トークンエンドポイント]]における [[OAuth 2.0]] の各[[承諾型]]の要求において、
[[クライアント認証]]を必須としなければ[['''なりません''']] [SRC[>>52, >>61, >>65, >>1, >>89]]。
[22] [[認可鯖]]は、[[クライアント型]]が[[機密]]の[[クライアント]]については、
自身の要件次第で任意の[[認証]]方式を使って[[認証]]して構いません [SRC[>>201]]。
[[認可鯖]]は、[[クライアント型]]が[[公開]]の[[クライアント]]についても[[認証]]して構いませんが、
[[クライアント]]の識別のためにこれに依存しては[['''なりません''']] [SRC[>>201]]。
;; [24] 一般的には[[合言葉]]や、[[公開鍵]]と[[秘密鍵]]の組のようなものを[[認可鯖]]が発行または登録して使います [SRC[>>201]]。[[クライアントの登録]]も参照。
[25] [[認可鯖]]は、
[[トークンエンドポイント]]における [[OAuth 2.0]] の各[[承諾型]]の要求に[[クライアント認証]]が含まれていれば、[[認証]]しなければ[['''なりません''']]
[SRC[>>52, >>61, >>65, >>1]]。
;; [23] [[OAuth 2.0クライアント認証]]は[[クライアント]]と[[認可鯖]]の間の任意の[[エンドポイント]]で利用可能な形で規定されてはいますが、実際に利用されるのは[[トークンエンドポイント]]でのみです。
* 認証方式
[3] 具体的な方式は、[[認可サーバー]]が決めることができます。複数の方法を提供する場合は、
その中から[[クライアント]]が選択できます。
[26] 複数の[[認証]]方法を単独の[[要求]]で併用しては[['''なりません''']] [SRC[>>201]]。
[110] [[OAuth 2.0]] としては[[認証]]方式に特に名前を与えていませんが、
[[OpenID Connect]] は名前を定義 [SRC[>>109]] しています。次の[[認証]]方式があります。
[FIG(short list)[
- [CODE@en[[[client_secret_basic]]]]
- [CODE@en[[[client_secret_post]]]]
- [CODE@en[[[client_secret_jwt]]]]
- [CODE@en[[[private_key_jwt]]]]
- [CODE@en[[[none]]]]
]FIG]
[27] [[認可鯖]]は、[[合言葉]]で[[認証]]する時は、 [[TLS]] を要求しなければ[['''なりません''']]
[SRC[>>201, >>89]]。また[[総当たり攻撃]]に対して[[エンドポイント]]を保護しなければ[['''なりません''']]
[SRC[>>201]]。
[60] [[認可鯖]]は[[基本認証]]以外の[[HTTP認証]]方式に対応しても構いませんが、
[[クライアント識別子]]と当該認証方式との対応関係を定義しなければ[['''なりません''']]
[SRC[>>7]]。
[90] [[認可鯖]]は、[[Webアプリケーション]]たる[[クライアント]]に関して[[合言葉]]よりも強い[[認証]]手段を検討することが[RUBYB[推奨]@en[encourage]]されています。
[[Webアプリケーション]]は[[合言葉]]その他の [[credentials]] の[[機密]]性を維持しなければ[['''なりません''']]。 [SRC[>>89]]
* 認証方式 [CODE[none]]
[111] [DFN[[CODE@en[[[none]]]]]] は、[[クライアント認証]]なしを表します [SRC[>>109]]。
* 合言葉に基づく認証方式
[28] [RUBYB[[[合言葉]]]@en[password]]を使う場合、[[基本認証]]を使って構いません。
[[クライアント]]に[[合言葉]]を発行した[[認可鯖]]は、[[基本認証]]に対応しなければ[['''なりません''']]。
[SRC[>>201]]
;; [118] [[Google]] と [[Facebook]] [SRC[>>164]]、 [[GitHub]] [SRC[>>166]]
その他いくつかの[[サービス]] [SRC[>>119, >>133, >>142, >>147, >>159, >>163, >>185]]
は、少なくても[[ドキュメント]]に明記されている範囲では、
[[引数]]を使う方法のみ対応していて、[[基本認証]]には対応していないようです。
;; [130] [[Twitter]] など [SRC[>>129, >>144, >>175, >>181]] は[[基本認証]]にのみ対応しているようです。
;; [141] [[Spotify]] は[[基本認証]]を原則とし、[[引数]]を使う方法にも対応しています
[SRC[>>140]]。 [[Amazon]] は[[引数]]を使う方法を原則とし、[[基本認証]]にも対応しています
[SRC[>>180]]。
;; [174] [[Bitly]] は[[認可符号]]フローにおいては[[引数]]を使う方法のみ記載し、
[[資源所有者合言葉credentials]]フローにおいては[[基本認証]]のみ記載しています [SRC[>>172]]。
なお [[Bitly]] は[[トークンエンドポイント]]において[[基本認証]]のみ、
または[[基本認証]]と [CODE(URI)@en[[[client_id]]]] および [CODE(URI)@en[[[client_secret]]]]
の指定によって[[アクセストークン]]を取得する独自のフローを実装しており [SRC[>>172]]、
その場合[[基本認証]]は[[資源所有者]]の[[利用者名]]と[[合言葉]]になります。
;; [191] [[Ci]] は [CODE@en[[[grant_type]]=[[password]]]] で[[資源所有者合言葉credentials]]
フローを装っていますが、[[クライアント]]の認証を[[引数]]によって行い、
[[資源所有者]]の認証を[[基本認証]]によって行う [SRC[>>190]] としており、
[[OAuth 2.0]] とは異なっています。
;; [155] [[Salesforce]] は[[引数]]を使う方法と、 [[JWT]] を使う方法に対応しています
[SRC[>>154, >>153]]。
** 認証方式 [CODE[client_secret_basic]]
[29] [[基本認証]]を使う場合、[[利用者名]]は[[クライアント識別子]]を [[UTF-8]] で
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[符号化]]したもの、
[[合言葉]]は[[クライアント]]の[[合言葉]]を [[UTF-8]] で
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]] [[符号化]]したものとします。
[SRC[>>7]] これを [DFN[[CODE@en[[[client_secret_basic]]]]]] と呼びます [SRC[>>109]]。
;; [30] 入力が名前と値の組でないわけですが、
[CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
版[[パーセント符号化]]を使うという意味だと思われます。
[31] なぜか[[認可鯖]]側の解釈の方法は規定されていません。
;; [32] どの[[文字]]が[[パーセント符号化]]されるのか [[RFC]] および参照先の [[HTML4]]
では曖昧なので、[[鯖]]は一旦[[復号]]してから比較する必要がありそうです。
** 認証方式 [CODE[client_secret_post]]
[33] [[認可鯖]]は、 [[payload body]] に[[引数]]を指定する方式に対応しても構いません。
しかし[[クライアント]]は[[基本認証]]を使えない場合のみこの方法を使う[['''べきです''']]。
[[payload body]] でなく[[要求URL]]中で指定しては[['''なりません''']]。 [SRC[>>7]]
これを [DFN[[CODE@en[[[client_secret_post]]]]]] と呼びます [SRC[>>109]]。
[59] その場合、[[クライアント]]は [CODE(URI)@en[[[client_id]]]] [[引数]]に[[クライアント識別子]]を、
[CODE(URI)@en[[[client_secret]]]] [[引数]]に[RUBYB[クライアント秘密]@en[client secret]]を指定しなければ[['''なりません''']]。
ただし[[クライアント秘密]]が[[空文字列]]なら、 [CODE(URI)@en[[[client_secret]]]]
[[引数]]は省略できます。 [SRC[>>7]]
;; [57] [CODE(URI)@en[[[client_secret]]]] [[引数]]の構文上の制約により、
この方法を使うなら[[合言葉]]に含められるのは[[印字可能ASCII文字]]に限られます。
* assertion に基づく認証方式
[112] [[OpenID Connect]] は [[JWT]] 形式で [CODE(URI)@en[[[client_assertion]]]]
[[引数]]と [CODE(URI)@en[[[client_assertion_type]]]] [[引数]]を指定する[[クライアント認証]]方式を
[CODE@en[[[client_secret_jwt]]]], [CODE@en[[[private_key_jwt]]]]
の2通り規定しています。
[5] [[RFC 7521]] は [CODE(URI)@en[[[client_assertion]]]]
[[引数]]と [CODE(URI)@en[[[client_assertion_type]]]] [[引数]]と省略可能な
[CODE(URI)@en[[[client_id]]]] [[引数]]を使った [[assertion]]
による[[クライアント認証]]方式 [SRC[>>4]] を規定しています。
* クライアント認証 credentials に関する要件
[81] [[認可鯖]]は、[[ネイティブアプリケーション]]や[[利用者エージェントベースのアプリケーション]]である[[クライアント]]に[[クライアント認証]]用の[[合言葉]]その他の
[[credentials]] を発行しては[['''なりません''']]。ただし[[ネイティブアプリケーション]]を特定の[[装置]]上で動作させたものに対しては[[合言葉]]その他の [[credentials]]
を発行しても構いません。 [SRC[>>89]]
[94] [[認可鯖]]は、推測による攻撃を防がなければ[['''なりません''']]。
生成された[[トークン]]の場合、
攻撃者が推測できる確率は 2[SUP[-128]] [[以下]]で[['''なければならず''']]、
2[SUP[-160]] [[以下]]である[['''べきです''']]。
そうでない[[末端利用者]]が扱う[[credentials]]の場合でも、
何らかの方法で保護しなければ[['''なりません''']]。 [SRC[>>89]]
[91] [[認可鯖]]は、[[クライアント認証]]が不可能な時に、
[[クライアント]]の [[identity]] を[RUBYB[検証]@en[validate]]する他の手段を用いる[['''べき''']]です。
例えば、[[リダイレクトURL]]を登録させたり、[[資源所有者]]に協力させたりできます。
[[認可鯖]]は、性質上[[認証]]できない[[クライアント]]については[[リダイレクトURL]]
の登録を求めなければ[['''なりません''']]。それ以外でも不正な[[クライアント]]から[[資源所有者]]を保護する方策をとる[['''べきです''']]。
[[リダイレクトURL]]が正しいからといって[[クライアント]]の [[identity]]
の検証には不十分ではありますが、 [[credentials]] を不正な[[クライアント]]に渡してしまうことは防止できます。 [SRC[>>89]]
[92] [[認可鯖]]は認証していない[[クライアント]]とのやりとりの[[セキュリティー]]を勘案し、
[[更新トークン]]など他の [[credentials]] を渡さないなど注意しなければなりません [SRC[>>89]]。
;; [44] [[認可鯖]]は[[クライアント認証]]を次の目的で使います [SRC[>>34]]。
[FIG(list)[
- [45] [[更新トークン]]や[[認可符号]]とその発行先の[[クライアント]]との紐付け。
[[認可符号]]を安全でない[[通信路]]で[[リダイレクトエンドポイント]]に送る時や[[リダイレクトURL]]
が完全に登録されていない時には特に重要です。
- [46] [[クライアント]]を無効化したり、[[credentials]] を変更したりして、
[[更新トークン]]が漏洩した時に濫用を防止。[[更新トークン]]をすべて変更するよりはこちらの方が容易です。
- [47] [[credentials]] の定期的な[RUBYB[入れ替え]@en[rotation]]を含む[[認証]]管理で良いとされている慣習の実行。
[[更新トークン]]をすべて入れ替えるのは大変ですが、[[クライアントcredentials]]一式だけならずっと容易です。
]FIG]
;; [93] [[認可エンドポイント]]も参照。
* 実装
[REFS[
- [164] [CITE@ja[Access Tokens]] ([TIME[2015-03-05 18:03:06 +09:00]] 版) <https://developers.facebook.com/docs/facebook-login/access-tokens>
- [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>
- [159] [CITE@en[SurveyMonkey - Guide OAuth]] ([TIME[2015-03-05 17:23:37 +09:00]] 版) <https://developer.surveymonkey.com/mashery/guide_oauth>
- [166] [CITE@en[OAuth | GitHub API]] ([TIME[2015-03-05 18:02:01 +09:00]] 版) <https://developer.github.com/v3/oauth/>
- [129] [CITE[Application-only authentication | Twitter Developers]] ([TIME[2015-03-05 10:58:24 +09:00]] 版) <https://dev.twitter.com/oauth/application-only>
- [133] [CITE[1. OAuth認証 - ヤマレコ Web API]] ([TIME[2015-02-25 16:41:06 +09:00]] 版) <https://sites.google.com/site/apiforyamareco/api/oauth>
- [140] [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/>
- [142] [CITE@en[OAuth | Slack]] ([[Slack]] 著, [TIME[2015-03-05 16:04:09 +09:00]] 版) <https://api.slack.com/docs/oauth>
- [144] [CITE@en[OAuth2 · reddit/reddit Wiki]] ([TIME[2015-03-05 16:29:00 +09:00]] 版) <https://github.com/reddit/reddit/wiki/OAuth2#user-content-token-retrieval-code-flow>
- [147] [CITE@ja[• Instagram Developer Documentation]] ([TIME[2015-03-05 16:42:50 +09:00]] 版) <https://instagram.com/developer/authentication/>
- [154] [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>
- [153] [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>
- [163] [CITE@en[Authenticating with OAuth 2.0 | LinkedIn Developer Network]] ([TIME[2015-03-05 17:56:22 +09:00]] 版) <https://developer.linkedin.com/docs/oauth2>
- [172] [CITE[Bitly API Documentation]] ([TIME[2014-11-01 00:33:47 +09:00]] 版) <http://dev.bitly.com/authentication.html>
- [175] [CITE[docomo Developer support API 共通リファレンス 第 2.0.4 版]] ([TIME[2015-03-02 17:25:25 +09:00]] 版) <https://devsite-pro.s3.amazonaws.com/contents_file/API_common_reference_latest.pdf>
- [180] [CITE[Login with Amazon Developer Guide for Websites]] ([TIME[2015-01-20 08:36:09 +09:00]] 版) <https://images-na.ssl-images-amazon.com/images/G/01/lwa/dev/docs/website-developer-guide._TTH_.pdf>
- [181] [CITE[Yahoo OAuth 2.0 Guide - Yahoo Developer Network]] ([TIME[2015-03-06 08:52:24 +09:00]] 版) <https://developer.yahoo.com/oauth2/guide/>
- [185] [CITE@en[Dropbox - Core API - endpoint reference]] ([TIME[2015-03-06 09:07:10 +09:00]] 版) <https://www.dropbox.com/developers/core/docs>
- [190] [CITE[Ci API Reference]] ([TIME[2015-02-26 23:06:44 +09:00]] 版) <http://developers.cimediacloud.com/#using-ci-user-credentials>
]REFS]
* 関連
[103] 本項の[[クライアント認証]]は、 [[SSLクライアント認証]]とは関係ありません。
;; [300] 理論上は [[TLSクライアント認証]]を [[OAuth 2.0クライアント認証]]の実現方式として採用することもできますが...