Microsoft ID プラットフォームと OAuth 2.0 リソース所有者のパスワード資格情報
Microsoft ID プラットフォームでは、OAuth 2.0 リソース所有者パスワード資格情報 (ROPC) の付与がサポートされています。これにより、アプリケーションは自分のパスワードを直接処理してユーザーにサインインできます。 この記事では、アプリケーション内のプロトコルに対して直接プログラムする方法について説明します。 可能な場合は、代わりにサポートされている Microsoft 認証ライブラリ (MSAL) を使用してトークンを取得し、セキュリティで保護された Web API 呼び出することをお勧めします。 また、MSAL を使用するサンプル アプリも参照してください。
警告
Microsoft は、ROPC フローを使用 "しない" ことをお勧めします。多要素認証 (MFA) と互換性がありません。 ほとんどのシナリオでは、より安全な代替手段が利用でき、推奨されます。 このフローでは、アプリケーションに非常に高い信頼が必要であり、他のフローに存在しないリスクが伴います。 このフローは、より安全なフローが実行できない場合にのみ使用してください。
重要
- Microsoft ID プラットフォームでは、個人アカウントではなく、Microsoft Entra テナント内の ROPC 許可のみがサポートされます。 つまり、テナント固有のエンドポイント (
https://login.microsoftonline.com/{TenantId_or_Name}
) またはorganizations
エンドポイントを使用する必要があります。 - Microsoft Entra テナントに招待された個人アカウントでは、ROPC フローを使用できません。
- パスワードを持たないアカウントは ROPC でサインインできません。つまり、SMS サインイン、FIDO、Authenticator アプリなどの機能は、そのフローでは機能しません。 アプリまたはユーザーがこれらの機能を必要とする場合は、ROPC 以外の許可の種類を使用します。
- ユーザーが 多要素認証 (MFA) を使用してアプリケーションにログインする必要がある場合は、代わりにブロックされます。
- ROPC は、ハイブリッド ID フェデレーション シナリオ ではサポートされていません (たとえば、オンプレミス アカウントの認証に使用される Microsoft Entra ID と AD FS)。 ユーザーがフル ページでオンプレミスの ID プロバイダーにリダイレクトされた場合、Microsoft Entra ID は、その ID プロバイダーに対してユーザー名とパスワードをテストできません。 ただし、パススルー認証 は ROPC でサポートされています。
- ハイブリッド ID フェデレーション シナリオの例外は、次のようになります。AllowCloudPasswordValidation が TRUE に設定 ホーム領域検出ポリシーを使用すると、オンプレミスのパスワードがクラウドに同期されるときに、フェデレーション ユーザーに対して ROPC フローが機能するようになります。 詳細については、「レガシ アプリケーションのフェデレーション ユーザーの直接 ROPC 認証を有効にする」を参照してください。
- 先頭または末尾の空白を含むパスワードは、ROPC フローではサポートされていません。
ROPC から移行する方法
MFA の普及に合わせて、一部の Microsoft Web API は、MFA 要件に合格した場合にのみアクセス トークンを受け入れます。 ROPC に依存するアプリケーションとテスト リグはロックアウトされます。Microsoft Entra はトークンを発行しないか、リソースが要求を拒否します。
ROPC を使用して保護されたダウンストリーム API を呼び出すトークンを取得する場合は、セキュリティで保護されたトークン取得戦略に移行します。
ユーザー コンテキストが使用可能な場合
エンド ユーザーがリソースにアクセスする必要がある場合、そのユーザーに代わって動作するクライアント アプリケーションは、対話型認証の形式を使用する必要があります。 エンド ユーザーは、ブラウザーでプロンプトが表示された場合にのみ MFA にチャレンジできます。
- Web アプリケーションの場合:
- Web API はブラウザーを表示できません。 代わりに、クライアント アプリケーションにチャレンジを返す必要があります。 詳細については、Web API と、Web API でユーザーにチャレンジする方法に関する記事を参照してください。
- デスクトップ アプリケーションでは、ブローカー ベースの認証を使用する必要があります。 ブローカーはブラウザーベースの認証を使用するため、MFA を適用し、可能な限り最も安全な体制を実現できます。
- また、ブローカー (Authenticator、ポータル サイト) ベースの認証を使用するようにモバイル アプリケーションを構成する必要があります。
ユーザー コンテキストが使用できない場合
ユーザー コンテキストが関係しないシナリオの例を次に示しますが、これらに限定されません。
- CI パイプラインの一部として実行されているスクリプト。
- ユーザーの詳細なしで、それ自体に代わってリソースを呼び出す必要があるサービス。
アプリケーション開発者は、サービス プリンシパル認証を使用する必要があります。これは、デーモンのサンプルに示されています。 MFA はサービス プリンシパルには適用されません。
サービス プリンシパルとして認証するには、複数の方法があります。
- アプリが Azure インフラストラクチャで実行されている場合は、マネージド ID 使用します。 マネージド ID を使用すると、シークレットと証明書を維持およびローテーションするオーバーヘッドが排除されます。
- GitHub などの別の OAuth2 準拠 ID プロバイダーによって管理されているシステムでアプリが実行されている場合は、フェデレーション ID 資格情報を使用します。
- マネージド ID またはフェデレーション ID を使用できない場合は、証明書資格情報を使用します。
警告
ユーザー コンテキストが使用可能な場合は、サービス プリンシパル認証を使用しないでください。 アプリ専用アクセスは本質的に高い特権であり、多くの場合、テナント全体のアクセス権が付与され、悪いアクターが任意のユーザーの顧客データにアクセスできる可能性があります。
プロトコル図
次の図は、ROPC フローを示しています。
を示す図
承認要求
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=00001111-aaaa-2222-bbbb-3333cccc4444
&scope=user.read%20openid%20profile%20offline_access
&username=MyUsername@myTenant.com
&password=SuperS3cret
&grant_type=password
パラメーター | 条件 | 説明 |
---|---|---|
tenant |
必須 | ユーザーをログインさせるディレクトリ テナント。 テナントは GUID またはフレンドリ名の形式で指定できます。 ただし、そのパラメーターを common または consumers に設定することはできませんが、organizations に設定できます。 |
client_id |
必須 | Microsoft Entra 管理センターのアプリ登録 ページで、あなたのアプリに割り当てられたアプリケーション (クライアント) ID。 |
grant_type |
必須 | password に設定する必要があります。 |
username |
必須 | ユーザーのメール アドレス。 |
password |
必須 | ユーザーのパスワード。 |
scope |
推奨 | アプリが必要とするスコープ、つまりアクセス許可をスペースで区切った一覧。 対話型フローでは、管理者またはユーザーは事前にこれらのスコープに同意する必要があります。 |
client_secret |
必要な場合がある | アプリがパブリック クライアントの場合、client_secret または client_assertion を含めることはできません。 アプリが機密クライアントの場合は、アプリを含む必要があります。 |
client_assertion |
必要な場合がある | 証明書を使用して生成された別の形式の client_secret 。 詳細については、「証明書資格情報 」を参照してください。 |
成功した認証応答
次の例は、成功したトークン応答を示しています。
{
"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 用ではないトークンに関する詳細を想定したりしないでください。
エラー応答
ユーザーが正しいユーザー名またはパスワードを指定していない場合、またはクライアントが要求された同意を受け取っていない場合、認証は失敗します。
エラー | 説明 | クライアント アクション |
---|---|---|
invalid_grant |
認証に失敗しました | 資格情報が正しくないか、クライアントが要求されたスコープに対する同意を持っていません。 スコープが付与されていない場合は、consent_required エラーが返されます。 このエラーを解決するには、クライアントは Web ビューまたはブラウザーを使用してユーザーを対話型プロンプトに送信する必要があります。 |
invalid_request |
要求が不適切に構築されました | 許可の種類は、/common または /consumers 認証コンテキストではサポートされていません。 代わりに、/organizations またはテナント ID を使用してください。 |
詳細情報
ROPC フローの実装例については、GitHub の .NET コンソール アプリケーション コード サンプルを参照してください。