Microsoft ID プラットフォームと OAuth 2.0 デバイス許可付与フロー
Microsoft ID プラットフォームでは、デバイス許可付与がサポートされています。これにより、ユーザーは、スマート TV、IoT デバイス、プリンターなどの入力制限のあるデバイスにサインインできます。 このフローを実現するには、デバイスのユーザーが別のデバイス上のブラウザーを使って Web ページにアクセスしてサインインするようにします。 ユーザーがサインインすると、デバイスは必要に応じてアクセス トークンと更新トークンを取得できます。
この記事では、アプリケーションでプロトコルに対して直接プログラミングする方法について説明します。 可能な場合は、トークンを取得してセキュリティで保護された Web API を呼び出す代わりに、サポートされている Microsoft 認証ライブラリ (MSAL) を使用することをお勧めします。 例については、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
パラメーター | 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_code と user_code の有効期限か切れるまでの秒数。 |
interval |
INT | ポーリング要求の間にクライアントが待機する秒数。 |
message |
String | ユーザーのための指示が含まれている、人間が判読可能な文字列。 これは、?mkt=xx-XX という形式でクエリ パラメーターを要求に含め、適切な言語カルチャ コードを入力することで、ローカライズできます。 |
注意
verification_uri_complete
応答フィールドは現時点では含まれておらず、サポートされていません。 このことに触れる理由は、標準を読むと、デバイス コード フロー標準のオプションの部分として verification_uri_complete
が示されているためです。
ユーザーの認証
クライアントが user_code
と verification_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 |
必須 | 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 用ではないトークンについての詳細を想定したりしないでください。