「[[マイクロソフト系技術情報 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] +----------+ +----------------+ | |>---(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) --validation_uri ---必須 ---承認のエンドユーザー検証URI ---手動入力可能なように短く。 --validation_uri_complete ---オプション。 ---QueryStringにuser_codeを含むvalidation_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で validation_uri_completeを使用すると、~ フィッシング攻撃が成立してしまうことがあるので使用しない。 --[[認可レスポンスのexpires_inを>#g6f8bd1d]]、~ いい塩梅に設定する(長過ぎず、短過ぎず)。 -device_code と user_codeの盗難 --セッションスパイ~ ショルダーハッキングのような。ディスプレイでか過ぎとか無いよね。 --ブートストラップ~ 通信チャネルは、デバイスの近くでのみ有効なものを選択する(見る、聞く、BLE)。 ***[[CIBAとの違い>CIBA(Client Initiated Backchannel Authentication)#se69e4c7]] [#ne289285] フローがRedirect等で一連の動作として繋がっておらず、~ TokenエンドポイントがPollingである点が共通的ではある。~ しかし、他の共通点は少なく、殆ど、別物と言える。 -登場人物 --コチラ: ---デバイス ---ユーザ(Resource Owner) --CIBA ---オペレータ(+[[CD>CIBA(Client Initiated Backchannel Authentication)#gfdf9430]]) ---ユーザ(Resource Owner)(+[[AD>CIBA(Client Initiated Backchannel Authentication)#n4cd6119]]) -ID --クライアント認証として、client_idのみ利用~ (client_secret は device_codeで代替するので不要)。 --追加でdevice_code、user_codeが必須となっている。~ (各、リクエスト・レスポンス間の紐付け的な意味で) ---device_code~ ・デバイスの特定の意味。~ ・client_secretの代替 ---user_code~ ・[[ユーザへの指示>#vd1fb219]]における要求の認可(承認)の意味。~ ・validation_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]]