「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>OAuth 2.0 拡張]]

* 目次 [#kdf99992]
#contents

*概要 [#je6ed00d]
http://self-issued.info/?p=1959

と言った理由で、[[OAuth 2.0 Device Flow]]から変更された(v15から)。

**前提 [#vc86ddcd]
+Device(≒ Public Client)は、
++既にインターネットに接続されている状態。
++アウトバウンド&color(red){HTTPS};要求を作成できる。
++EndUser(≒ Resource Owner)にURIとコードを表示できる。
+EndUser(≒ Resource Owner)は、~
セカンダリデバイス(PCやスマホなど)を持っている。

**フロー [#eaa50cf2]
Verification URI が Verification URIにリネームされとる。
 +----------+                                +----------------+
 |          |>---(A)-- Client Identifier --->|                |
 |          |                                |                |
 |          |<---(B)-- Device Code,      ---<|                |
 |          |          User Code,            |                |
 |  Device  |          & Verification URI    |                |
 |  Client  |                                |                |
 |          |  [polling]                     |                |
 |          |>---(E)-- Device Code,      --->|                |
 |          |          & Client Identifier   |                |
 |          |                                |  Authorization |
 |          |<---(F)-- Access Token      ---<|     Server     |
 +----------+   (& Optional Refresh Token)   |                |
       v                                     |                |
       :                                     |                |
      (C) User Code & Verification URI       |                |
       :                                     |                |
       v                                     |                |
 +----------+                                |                |
 | End user |                                |                |
 |    at    |<---(D)-- End user reviews  --->|                |
 |  Browser |          authorization request |                |
 +----------+                                +----------------+

+ClientはAuthZ(N)Serverからの認可リクエストにclient_idを含める(A)。
+AuthZ(N)Serverは、Clientの認可リクエストに対して下記を応答する(B)。
--デバイス・コード
--エンドユーザ・コード
--エンドユーザ検証URI
+Clientは、EndUser(≒ Resource Owner)に(別のデバイス上の)User-Agentを使用し、~
エンドユーザ検証URIにアクセスしエンドユーザ・コードを入力するように指示(C)。~
~
+User-Agent
--AuthZ(N)ServerはUser-Agentを介しEndUser(≒ Resource Owner)を認証。
--許可リクエストに同意した場合、User-Agentからエンドユーザ・コードを入力、AuthZ(N)Serverで検証(D)。
+Client~
AuthZ(N)Serverを繰り返しPolling(デバイス・コードとclient_id)(E)~
~
+AuthZ(N)Serverは、~
Clientから提供されたデバイス・コードとclient_idを検証し、~
EndUser(≒ Resource Owner)が、アクセスを、
--許可した場合はaccess_tokenで応答し、(F)
--拒否した場合はエラーを返す。

*詳細 [#x1cbd2e0]

**認可エンドポイント [#j07dba0e]
認証リクエストを受け付けて直ちにレスポンスする(以後、非同期的に処理)。

***認可リクエスト [#v2dff676]
-ポイントは
--POSTであること。
--client_secretは不要。

-リクエスト例
 POST /device_authorization HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
 
 client_id=459691054427

***認可レスポンス [#g6f8bd1d]
-パラメタ

--device_code
---必須。
---デバイス・コード(デバイスを検証するコード)。
---高いエントロピーを要求(GUID位の長さか?)

--user_code
---必須。
---エンドユーザー確認コード。
---BCDFGHJKLMNPQRSTVWXZ(基数20)から8文字(XXXX-XXXX)
---9桁の有効数字(nnn-nnn-nnn)

--verification_uri
---必須
---承認のエンドユーザー検証URI
---手動入力可能なように短く。

--verification_uri_complete
---オプション。
---QueryStringにuser_codeを含むverification_uri
---[[QRコード>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?QR%E3%82%B3%E3%83%BC%E3%83%89]]やNFCなどのURIでブラウザが開かれる方法を使用する。

--expires_in
---必須
---device_code、user_codeの有効期間(秒)。

--interval
---オプション。
---Polling間隔~
最小の待機時間(秒)~
デフォルトは5(秒)

-レスポンス例
 HTTP/1.1 200 OK
 Content-Type: application/json
 Cache-Control: no-store
 
 {
   "device_code": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS",
   "user_code": "WDJB-MJHT",
   "verification_uri": "https://example.com/device",
   "verification_uri_complete": "https://example.com/device?user_code=WDJB-MJHT",
   "expires_in": 1800,
   "interval": 5
 }

***エラーの返却 [#q81daebd]
POSTのJSON返却なので、[[Tokenエンドポイントのレスポンス(失敗)>#y071fbf5]]と同じ。

**ユーザへの指示 [#vd1fb219]
Resource Owner(EndUser)への指示。

-user_code and verification_uri
-verification_uri_complete (optional)

※ device_codeは、混乱を招くため、対話中に表示しない。

***表示例 [#v6fc8875]
-「verification_uri」
 +-----------------------------------------------+
 |                                               |
 |  Using a browser on another device, visit:    |
 |  https://example.com/device                   |
 |                                               |
 |  And enter the code:                          |
 |  WDJB-MJHT                                    |
 |                                               |
 +-----------------------------------------------+

-「verification_uri」 and 「verification_uri_complete (by [[QR code>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?QR%E3%82%B3%E3%83%BC%E3%83%89]])」
 +-------------------------------------------------+
 |                                                 |
 |  Scan the QR code, or using     +------------+  |
 |  a browser on another device,   |[_]..  . [_]|  |
 |  visit:                         | .  ..   . .|  |
 |  https://example.com/device     | . .  . ....|  |
 |                                 |.   . . .   |  |
 |  And enter the code:            |[_]. ... .  |  |
 |  WDJB-MJHT                      +------------+  |
 |                                                 |
 +-------------------------------------------------+

-その他

--テキスト読み上げオーディオ

--Bluetooth Low Energy(BLE)による
---非ブラウザユーザーインタラクション(コンパニオンアプリの利用)
---ただし、verification_uri以外の操作は仕様の範囲外。

***手順 [#ec4fcf1d]
+Resource Owner(EndUser)は、AuthZ(N)Server の verification_uri(HTTPS)に移動、
+user_codeを入力し、AuthZ(N)Serverに送信(デバイス認可セッションの識別のため)~
※ user_code入力画面への遷移前のサインアップ、追加のセキュリティ検証などの手順を追加可能。
+この後に表示される画面で、同意 / 拒否 を回答して、AuthZ(N)Serverに再送信。
+Device(≒ Public Client)はdevice_codeで[[Tokenエンドポイント>#jc7072d2]]を継続的にPolling
--ユーザーが対話を完了するか、
--コードが期限切れになるか、
--別のエラーが発生するまで。

***セキュリティ考慮事項 [#ca27d993]
user_code入力の試行回数は、5回(アルファベットで8文字程度)。

**Tokenエンドポイント [#jc7072d2]

***Tokenリクエスト [#q060f6cb]
デバイス上のプロンプトに表示した後、TokenリクエストのPollingを始める。

-パラメタ
--grant_type=urn:ietf:params:oauth:grant-type:device_code
--device_code
--client_id

-リクエスト例
 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
 
 grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code
 &device_code=GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS
 &client_id=459691054427

***Tokenレスポンス [#y071fbf5]
-成功~
[[OAuth 2.0>OAuth#n037bd41]]の認可レスポンス(成功)と同じ。

-失敗~
[[OAuth 2.0>OAuth#n037bd41]]の認可レスポンス(失敗)に以下のパラメタを追加

--パラメタ(≒エラーコード)

---authorization_pending~
認可リクエストは保留中

---slow_down~
"authorization_pending"の変形で~
Polling間隔を5秒遅らせろの意味。

---access_denied~
Resource Owner(EndUser)は、認可(承認)要求を拒否。

---expired_token~
device_codeの有効期限が切れ。

--レスポンス例
 HTTP/1.1 400 Bad Request
 Content-Type: application/json;charset=UTF-8
 Cache-Control: no-store
 Pragma: no-cache
 
 {
   "error":"authorization_pending"
 }

***ポイント [#r8317089]
-Pollingなので、

--過負荷にならないように注意する。
--[[Exponential Backoff(指数関数的に増えるリトライ間隔)>Exponential Backoff(指数バックオフ)]]推奨

--自動的ではなく、デバイス上のプロンプトに表示された場合~
にのみデバイス認可(承認)要求~Pollingを開始するなど。

-Polling以外の選択肢
--リターンチャネルが存在する場合、Polling以外の選択肢も選択可能。
--しかし、このような動作はこの仕様の範囲外~
([[CIBAではコレを仕様で決めているがPollingを行うCDはDeviceでは無いな...>CIBA(Client Initiated Backchannel Authentication)#qe881045]])。

-クライアント認証~
client_id と device_code(client_secret代替)

**その他 [#dc21382a]

***メタデータ [#x9f13e99]
-grant_types_supported に urn:ietf:params:oauth:grant-type:device_code を追加。
-エンドポイントとして、device_authorization_endpoint を追加。

***セキュリティ考慮事項 [#h294d81a]
-Deviceは、Public Clientで、PKCEとの違いは、~
認可リクエストと実際の認可を行うデバイスが異なる事。

--認可を行うデバイスは信頼できるが、~
認可リクエスト、Tokenリクエストを行うデバイスの信頼性は微妙

--なので、device_code を client_secret代替として使用する。~
(紐付けのタメのuser_codeは、実際の認可を行うデバイスから入力する)

-中間者攻撃
--Device購入者は、Deviceと開発・販売元が信頼できると期待している。
--これがハズれると、中間者攻撃が成立してしまうことがある。

-フィッシング
--e-mailやSMSで verification_uri_completeを使用すると、~
フィッシング攻撃が成立してしまうことがあるので使用しない。

--[[認可レスポンスのexpires_inを>#g6f8bd1d]]、~
いい塩梅に設定する(長過ぎず、短過ぎず)。

-device_code と user_codeの盗難

--セッションスパイ~
ショルダーハッキングのような。ディスプレイでか過ぎとか無いよね。

--ブートストラップ~
通信チャネルは、デバイスの近くでのみ有効なものを選択する(見る、聞く、BLE)。

***[[CIBAとの違い>CIBA(Client Initiated Backchannel Authentication)#se69e4c7]] [#ne289285]

フローがRedirect等で一連の動作として繋がっておらず、~
TokenエンドポイントがPollingである点が共通的ではある。~
しかし、他の共通点は少なく、殆ど、別物と言える。

-登場人物

--コチラ:
---デバイス(Client)
---AuthZ (AuthN) Server
---ユーザ(Resource Owner)

--CIBA
---オペレータ(+[[CD>CIBA(Client Initiated Backchannel Authentication)#gfdf9430]](Client))
---AuthZ (AuthN) Server
---ユーザ(Resource Owner)(+[[AD>CIBA(Client Initiated Backchannel Authentication)#n4cd6119]])

-ID

--クライアント認証として、client_idのみ利用~
(client_secret は~
%%device_codeで代替するので不要%%~
Public Clientの場合もあるから使用しない)。

--追加でdevice_code、user_codeが必須となっている。~
(各、リクエスト・レスポンス間の紐付け的な意味で)

---device_code~
・デバイスの特定の意味。~
・client_secretの代替

---user_code~
・[[ユーザへの指示>#vd1fb219]]における要求の認可(承認)の意味。~
・verification_uri_completeを使用すれば、入力は省略できる。~

--CIBAでは、以下に依存

---[[client_id + client_secret>OAuth#i7b73962]] or [[JWT系>JWTとOAuth2.0#pebd83d3]]のクライアント認証を使用。~
(だたし、CIBA FAPI Profileでは後者が必須となっている)


---code や msg を使用して、[[AD>CIBA(Client Initiated Backchannel Authentication)#n4cd6119]]へのプッシュ通知と応答の正当性を確認。

---auth_req_idでPolling(モードによってはclient_notification_tokenを使用)

-code や msg

--device_code

---CIBAには存在せず、コチラでは必須。
---デバイスの特定のために使用する。
---CIBAのauth_req_idの様に、Pollingで使用する。

--user_code

---CIBAではoptionalだったがコチラでは必須。

---CIBAでは「未認証[[AD>CIBA(Client Initiated Backchannel Authentication)#n4cd6119]]」の応答入力用だが、~
コチラでは、[[ユーザへの指示>#vd1fb219]]における要求の認可(承認)入力用~

--binding_message~

---CIBAではoptionalだったがコチラには無い。~
(だたし、CIBA FAPI Profileでは必須となっている)

---画面表示用~
CIBAのオペレータからユーザに口頭 ,etc. で伝える。

-Tokenエンドポイント

--Polling
---コチラ:[[Exponential Backoff>#r8317089]]
---CIBA:Exponential Backoffの指定なし

--フロント or バック
---コチラ:フロントチャネル
---CIBA:バックチャネル

-ココまで書いて気が付いたが、本フロー、~
何気に以下の延長のクライアント認証っぽい。
--[[Resource Owner Password Credentialsグラント種別>OAuth#zfff6f89]]
--[[JWT bearer token authorizationグラント種別>JWTとOAuth2.0#f5007063]]

>確かに、ユーザではなく、デバイス(クライアント)を認証している。

*参考 [#j86047dc]
2019年8月にDraftからRFC化がされている。

-RFC 8628 - OAuth 2.0 Device Authorization Grant~
https://tools.ietf.org/html/rfc8628

-OAuth 2.0 Device Authorization Grant~
(draft-ietf-oauth-device-flow)~
https://tools.ietf.org/html/draft-ietf-oauth-device-flow

-Device Authorization Grantやってみた - Auth屋ブログ~
https://www.authya.com/2019/11/device-authorization-grant.html

**内部リンク [#e46addd7]

***[[OAuth 2.0 Device Flow]] [#nd8fe690]

***[[CIBA(Client Initiated Backchannel Authentication)]] [#r107e952]

----
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS