Microsoft ID プラットフォームと OAuth 2.0 リソース所有者のパスワード資格情報

Microsoft ID プラットフォームでは、OAuth 2.0 リソース所有者のパスワード資格情報 (ROPC) 付与がサポートされています。これにより、アプリケーションでは、ユーザーのパスワードを直接処理することでユーザーをサインインさせることができます。 この記事では、アプリケーションでプロトコルに対して直接プログラミングする方法について説明します。 可能な場合は、トークンを取得してセキュリティで保護された Web API を呼び出す代わりに、サポートされている Microsoft 認証ライブラリ (MSAL) を使用することをお勧めします。 また、MSAL を使用するサンプル アプリも参照してください。

警告

ROPC フローは "使用しない" ことをお勧めします。 ほとんどのシナリオでは、より安全な代替手段を利用でき、推奨されます。 このフローでは、アプリケーションで非常に高い信頼度が要求されるため、他のフローには存在しないリスクが伴います。 このフローは、より安全なフローが実行可能ではない場合にのみ使用してください。

重要

  • Microsoft ID プラットフォームでは、Azure AD テナント内での ROPC 許可をサポートしています。個人用アカウントは対象外です。 そのため、テナント固有のエンドポイント (https://login.microsoftonline.com/{TenantId_or_Name}) または organizations エンドポイントを使用する必要があります。
  • Azure AD テナントに招待された個人用アカウントでは、ROPC フローを使用できません。
  • パスワードがないアカウントは ROPC でサインインできません。つまり、SMS サインイン、FIDO、および Authenticator アプリなどの機能は、そのフローでは動作しません。 アプリまたはユーザーにこれらの機能が必要な場合は、ROPC 以外の付与タイプを使用してください。
  • ユーザーが多要素認証 (MFA) を使用してアプリケーションにログインすると、ログインできずにブロックされます。
  • ROPC はハイブリッド ID フェデレーション シナリオ (たとえば、オンプレミスのアカウントの認証に使用される Azure AD や ADFS) ではサポートされていません。 ユーザーがオンプレミスの ID プロバイダーに全ページ リダイレクトされる場合、Azure AD ではその ID プロバイダーに対してユーザー名とパスワードをテストできません。 ただし、ROPC ではパススルー認証がサポートされています。
  • ハイブリッド ID フェデレーション シナリオの例外は次のとおりです。AllowCloudPasswordValidation が TRUE に設定されたホーム領域の検出ポリシーを使用すると、オンプレミス パスワードがクラウドに同期されるときに、ROPC フローがフェデレーション ユーザーに対して機能します。 詳細については、レガシ アプリケーションに対するフェデレーション ユーザーの直接 ROPC 認証を有効にする方法に関する記事を参照してください。
  • 先頭または末尾の空白を含むパスワードは、ROPC フローではサポートされていません。

ヒント

Postman でこの要求を実行してみる
Postman でこの要求やその他を実行してみてください。その際、トークンと ID を忘れずに置き換えてください。

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

次は ROPC フローの図です。

リソース所有者のパスワード資格情報フローを示す図

Authorization request (承認要求)

ROPC フローは 1 件の要求です。クライアント ID とユーザーの資格情報を ID プロバイダーに送信し、返されたトークンを受信します。 クライアントでは、これを行う前に、ユーザーの電子メール アドレス (UPN) とパスワードを要求する必要があります。 クライアントでは、要求が成功した直後にユーザーの資格情報を安全な方法でメモリから破棄する必要があります。 保存してはなりません。

// Line breaks and spaces are for legibility only.  This is a public client, so no secret is required.

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

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20openid%20profile%20offline_access
&username=MyUsername@myTenant.com
&password=SuperS3cret
&grant_type=password
パラメーター 条件 説明
tenant 必須 ユーザーをログインさせるディレクトリ テナント。 テナントは GUID またはフレンドリ名の形式で指定できます。 ただし、このパラメーターは commonconsumers に設定できませんが、organizations には設定できます。
client_id 必須 Azure portal の [アプリの登録] ページでアプリに割り当てられたアプリケーション (クライアント) ID。
grant_type 必須 password に設定する必要があります。
username 必須 ユーザーの電子メール アドレス。
password 必須 ユーザーのパスワード。
scope 推奨 アプリで必要となるスコープ (アクセス許可) をスペースで区切った一覧。 対話型のフローでは、管理者またはユーザーが事前にこれらのスコープに同意する必要があります。
client_secret 必要な場合あり アプリがパブリック クライアントである場合、client_secret または client_assertion を含めることはできません。 アプリが機密クライアントである場合は、それを含める必要があります。
client_assertion 必要な場合あり 証明書を使用して生成された、client_secret の別の形式。 詳細については、証明書資格情報に関する記事を参照してください。

警告

このフローの使用をお勧めしないことの一環として、公式 SDK では、シークレットまたはアサーションを使用する機密クライアントに対してこのフローをサポートしていないことがあります。 使いたいと考えている SDK では、ROPC の使用中にシークレットを追加できない場合があります。

正常な認証応答

トークンの応答の成功例を次に示します。

{
    "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 用ではないトークンについての詳細を想定したりしないでください。

エラー応答

ユーザーが正しいユーザー名やパスワードを指定していない場合、あるいは要求した同意がクライアントに届いていない場合、認証は失敗します。

エラー 説明 クライアント側の処理
invalid_grant 認証に失敗しました 資格情報が正しくないか、要求したスコープに対してクライアントに同意がありません。 スコープが付与されていない場合、consent_required エラーが返されます。 このエラーを解決するには、クライアントで、Web ビューまたはブラウザーを利用し、対話式プロンプトにユーザーを送信する必要があります。
invalid_request 要求が正しく構築されていません この付与タイプは /common または /consumers 認証ではサポートされていません。 代わりに /organizations またはテナント ID を使用してください。

詳細情報

ROPC フローの実装例については、GitHub で .NET Core コンソール アプリケーションのコード サンプルをご覧ください。