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

Microsoft ID プラットフォームでは、デバイス許可付与がサポートされています。これにより、ユーザーは、スマート TV、IoT デバイス、プリンターなどの入力制限のあるデバイスにサインインできます。 このフローを実現するには、デバイスのユーザーが別のデバイス上のブラウザーを使って Web ページにアクセスしてサインインするようにします。 ユーザーがサインインすると、デバイスは必要に応じてアクセス トークンと更新トークンを取得できます。

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

プロトコルのダイアグラム

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

Device code flow

デバイス承認要求

クライアントはまず、認証を開始するために使用するデバイスとユーザー コードを認証サーバーに確認する必要があります。 クライアントはこの要求を /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

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

デバイス承認応答

正常終了の応答は、ユーザーがサインインできるようにするために必要な情報が含まれた JSON オブジェクトです。

パラメーター Format 説明
device_code String クライアントと承認サーバー間のセッションを検証するために使用される長い文字列。 クライアントはこのパラメーターを使用して、承認サーバーにアクセス トークンを要求します。
user_code String ユーザーに表示される短い文字列。セカンダリ デバイス上のセッションを識別するために使用されます。
verification_uri URI ユーザーがサインインするために user_code を使用してアクセスする必要がある URI。
expires_in INT device_codeuser_code の有効期限か切れるまでの秒数。
interval INT ポーリング要求の間にクライアントが待機する秒数。
message String ユーザーのための指示が含まれている、人間が判読可能な文字列。 これは、?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=535fb089-9ff3-47b6-9bfb-4f1264799865&device_code=GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...
パラメーター 必須 説明
tenant 必須 初期要求で使用されているのと同じテナントまたはテナント エイリアス。
grant_type 必須 urn:ietf:params:oauth:grant-type:device_code である必要があります。
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..."
}
パラメーター Format 説明
token_type String 常に Bearer
scope スペース区切りの文字列 アクセス トークンが返された場合、そのアクセス トークンが有効なスコープがリストされます。
expires_in INT 含まれているアクセス トークンが有効である秒数。
access_token 不透明な文字列 要求されたスコープに対して発行されます。
id_token JWT 元の scope パラメーターに openid スコープが含まれている場合に発行されます。
refresh_token 不透明な文字列 元の scope パラメーターに offline_access が含まれている場合に発行されます。

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

警告

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