次の方法で共有


Microsoft ID プラットフォームと OAuth 2.0 デバイス承認付与フロー

Microsoft ID プラットフォームでは、 デバイス承認付与がサポートされています。これにより、ユーザーはスマート テレビ、IoT デバイス、プリンターなどの入力に制約のあるデバイスにサインインできます。 このフローを有効にするには、ユーザーが別のデバイスのブラウザーの Web ページにアクセスしてサインインするようにデバイスに設定します。 ユーザーがサインインすると、デバイスは必要に応じてアクセス トークンと更新トークンを取得できます。

この記事では、アプリケーション内のプロトコルに対して直接プログラムする方法について説明します。 可能な場合は、代わりにサポートされている Microsoft 認証ライブラリ (MSAL) を使用してトークンを取得し、セキュリティで保護された Web API 呼び出することをお勧めします。 例として MSAL を使用するサンプル アプリ を参照できます。

プロトコル図

デバイス コード フロー全体を次の図に示します。 各手順については、この記事全体で説明します。

デバイス コード フロー

デバイス承認要求

クライアントは最初に、認証を開始するために使用するデバイスとユーザー コードを認証サーバーで確認する必要があります。 クライアントは、 /devicecode エンドポイントからこの要求を収集します。 要求には、ユーザーから取得する必要があるアクセス許可もクライアントに含める必要があります。

要求が送信された時点から、ユーザーはサインインに 15 分かかります。 これは、expires_inの既定値です。 要求は、ユーザーがサインインの準備ができていることを示した場合にのみ行う必要があります。

// Line breaks are for legibility only.

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode
Content-Type: application/x-www-form-urlencoded

client_id=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=user.read%20openid%20profile

パラメーター 条件 説明
tenant 必須 /common/consumers、または /organizations を指定できます。 GUID またはフレンドリ名形式でアクセス許可を要求するディレクトリ テナントを指定することもできます。
client_id 必須 [Microsoft Entra 管理センター - アプリの登録] エクスペリエンスからアプリに割り当てられたアプリケーション (クライアント) ID
scope 必須 ユーザーに同意を求める スコープ の、スペースで区切られたリスト。

デバイス承認応答

成功した応答は、ユーザーがサインインできるようにするために必要な情報を含む JSON オブジェクトです。

パラメーター 形式 説明
device_code クライアントと承認サーバーの間のセッションを確認するために使用される長い文字列。 クライアントはこのパラメーターを使用して、承認サーバーにアクセス トークンを要求します。
user_code セカンダリ デバイス上のセッションを識別するために使用されるユーザーに表示される短い文字列。
verification_uri URI(統一リソース識別子) サインインするためにユーザーが user_code で移動する URI。
expires_in 整数 (int) device_codeuser_code の有効期限か切れるまでの秒数。
interval 整数 (int) ポーリング要求の間にクライアントが待機する秒数。
message ユーザーの指示を含む人間が判読できる文字列。 これをローカライズするには、?mkt=xx-XXフォームの要求にクエリ パラメーターを含め、適切な言語カルチャ コードを入力します。

現時点では、 verification_uri_complete 応答フィールドは含まれていないか、サポートされていません。 これは、標準を読んだ場合、verification_uri_completeがデバイス コード フロー標準の省略可能な部分として一覧表示されるからです。

ユーザーの認証

クライアントが user_codeverification_uriを受信すると、値が表示され、ユーザーはモバイルまたは PC ブラウザーを使用してサインインするように指示されます。

ユーザーが /common または /consumersを使用して個人アカウントで認証を行った場合、認証状態をデバイスに転送するために、もう一度サインインするように求められます。 これは、デバイスがユーザーの Cookie にアクセスできないためです。 クライアントによって要求されたアクセス許可に同意するように求められます。 ただし、これは認証に使用される職場または学校アカウントには適用されません。

ユーザーがverification_uriで認証している間、クライアントは、device_codeを使用して、要求されたトークンの/token エンドポイントをポーリングする必要があります。

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=00001111-aaaa-2222-bbbb-3333cccc4444&device_code=GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...
パラメーター 必須 説明
tenant 必須 最初の要求で使用されるのと同じテナントまたはテナントエイリアス。
grant_type 必須 `Default` である必要があります。
client_id 必須 最初の要求で使用される client_id と一致する必要があります。
device_code 必須 デバイス承認要求で返される device_code

予期されるエラー

デバイス コード フローはポーリング プロトコルであるため、ユーザー認証が完了する前にクライアントに提供されるエラーが予想される必要があります。

エラー 説明 クライアント側の処理
authorization_pending ユーザーは認証を完了していませんが、フローを取り消していません。 少なくとも interval 秒後に要求を繰り返します。
authorization_declined エンド ユーザーが承認要求を拒否しました。 ポーリングを停止し、認証されていない状態に戻します。
bad_verification_code /token エンドポイントに送信されたdevice_codeが認識されませんでした。 クライアントが要求で正しい device_code を送信していることを確認します。
expired_token expires_inの値を超え、device_codeでは認証できなくなります。 ポーリングを停止し、認証されていない状態に戻します。

成功した認証応答

成功したトークン応答は次のようになります。

{
    "token_type": "Bearer",
    "scope": "User.Read profile openid email",
    "expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
    "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD..."
}
パラメーター 形式 説明
token_type 常に Bearer です。
scope スペース区切り文字列 アクセス トークンが返された場合、アクセス トークンが有効なスコープが一覧表示されます。
expires_in 整数 (int) 含まれているアクセス トークンが有効な秒数。
access_token 不透明な文字列 要求されたスコープに対して発行されます。
id_token JWT 元の scope パラメーターに openid スコープが含まれている場合に発行されます。
refresh_token 不透明な文字列 scope に元のパラメーター offline_accessが含まれている場合、発行されます。

更新トークンを使用すると、 OAuth コード フローのドキュメントに記載されているのと同じフローを使用して、新しいアクセス トークンと更新トークンを取得できます。

警告

この例のトークンをコードに含め、所有していない API のトークンの検証や読み取りを試みないでください。 Microsoft サービスのトークンでは、JWT として検証されない特殊な形式を使用できます。また、コンシューマー (Microsoft アカウント) ユーザー向けに暗号化することもできます。 トークンの読み取りは便利なデバッグおよび学習ツールですが、コード内でこれに依存したり、制御する API 用ではないトークンに関する詳細を想定したりしないでください。