Web API を呼び出すデスクトップ アプリ: 統合 Windows 認証でトークンを取得する

ドメインまたは Microsoft Entra 参加済みのマシンでドメイン ユーザーをサインインさせるには、統合 Windows 認証 (IWA) を使用します。

制約

  • 統合 Windows 認証は、"フェデレーション+" ユーザー (Active Directory で作成され、Microsoft Entra ID によってサポートされているユーザー) に対してのみ使用できます。 Microsoft Entra ID で直接作成され、Active Directory のサポートのないユーザー ("マネージド" ユーザーと呼ばれます) はこの認証フローを使用できません。 この制限は、ユーザー名とパスワードのフローには影響しません。

  • IWA では多要素認証 (MFA) はバイパスされません。 MFA が構成されている状況では、MFA チャレンジが必要な場合に IWA が失敗する可能性があります。これは、MFA でユーザーの操作が必要になるためです。

    IWA は非対話型ですが、MFA にはユーザーの操作が必要です。 ID プロバイダーが MFA の実行を要求するタイミングの制御は、ユーザーではなくテナント管理者が行います。 弊社の観測によると、MFA が必要なのは、他の国/地域からサインインする場合と VPN 経由で企業ネットワークに接続されていない場合です。ただし、VPN 経由で接続されている場合であっても MFA が必要になる可能性があります。 確定的なルール セットを想定しないでください。 Microsoft Entra ID では、AI を使用して、MFA が必要かどうかを継続的に学習します。 IWA が失敗した場合は、対話型認証やデバイス コード フローなどのユーザー プロンプトにフォールバックしてください。

  • PublicClientApplicationBuilder で渡される機関の要件は次のとおりです。

    • https://login.microsoftonline.com/{tenant}/ の形式でテナント化されている。ここで、tenant は、テナント ID を表す GUID またはテナントに関連付けられているドメインです。
    • 任意の職場および学校アカウント用である: https://login.microsoftonline.com/organizations/
    • Microsoft 個人アカウントはサポートされていません。 /common および /consumers テナントを使用することはできません。
  • 統合 Windows 認証はサイレント フローであるため、次の要件が適用されます。

    • アプリケーションのユーザーが、アプリケーションの使用に事前に同意しておく必要があります。
    • または、テナント管理者が、テナント内のすべてのユーザーによるアプリケーションの使用に事前に同意しておく必要があります。
    • つまり、以下の要件が適用されます。
      • 開発者が自分で Azure portal 上の [許可] ボタンを選択しておきます。
      • または、テナント管理者がアプリケーションの登録の [API のアクセス許可] タブにある [{テナント ドメイン} の管理者の同意を付与/取り消す] ボタンを選択しておきます。 詳細については、「Web API にアクセスするためのアクセス許可を追加する」を参照してください。
      • または、ユーザーがアプリケーションに同意する方法を指定しておきます。 詳細については、「個々のユーザーの同意を要求する」を参照してください。
      • または、テナント管理者がアプリケーションに同意する方法を指定しておきます。 詳細については、管理者の同意に関する記事を参照してください。
  • このフローは、.NET デスクトップ、.NET、UWP の各アプリに対して有効です。

同意の詳細については、Microsoft ID プラットフォームでのアクセス許可と同意に関する記事を参照してください。

使用方法の確認

MSAL.NET では、次のように使用します。

AcquireTokenByIntegratedWindowsAuth(IEnumerable<string> scopes)

通常、必要なパラメーターは 1 つだけです (scopes)。 Windows 管理者によるポリシーの設定方法に応じて、Windows マシン上のアプリケーションではサインインしているユーザーの検索が許可されない場合があります。 その場合は、2 番目のメソッドである .WithUsername() を使用して、サインインしているユーザーのユーザー名を UPN 形式で渡します (例: joe@contoso.com)。

次のサンプルは、最新のケース (および取得可能な例外の種類の説明とその軽減策) を示しています。

static async Task GetATokenForGraph()
{
 string authority = "https://login.microsoftonline.com/contoso.com";
 string[] scopes = new string[] { "user.read" };
 IPublicClientApplication app = PublicClientApplicationBuilder
      .Create(clientId)
      .WithAuthority(authority)
      .Build();

 var accounts = await app.GetAccountsAsync();

 AuthenticationResult result = null;
 if (accounts.Any())
 {
  result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
      .ExecuteAsync();
 }
 else
 {
  try
  {
   result = await app.AcquireTokenByIntegratedWindowsAuth(scopes)
      .ExecuteAsync(CancellationToken.None);
  }
  catch (MsalUiRequiredException ex)
  {
   // MsalUiRequiredException: AADSTS65001: The user or administrator has not consented to use the application
   // with ID '{appId}' named '{appName}'.Send an interactive authorization request for this user and resource.

   // you need to get user consent first. This can be done, if you are not using .NET (which does not have any Web UI)
   // by doing (once only) an AcquireToken interactive.

   // If you are using .NET or don't want to do an AcquireTokenInteractive, you might want to suggest the user to navigate
   // to a URL to consent: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read

   // AADSTS50079: The user is required to use multi-factor authentication.
   // There is no mitigation - if MFA is configured for your tenant and AAD decides to enforce it,
   // you need to fallback to an interactive flows such as AcquireTokenInteractive or AcquireTokenByDeviceCode
   }
   catch (MsalServiceException ex)
   {
    // Kind of errors you could have (in ex.Message)

    // MsalServiceException: AADSTS90010: The grant type is not supported over the /common or /consumers endpoints. Please use the /organizations or tenant-specific endpoint.
    // you used common.
    // Mitigation: as explained in the message from Azure AD, the authority needs to be tenanted or otherwise organizations

    // MsalServiceException: AADSTS70002: The request body must contain the following parameter: 'client_secret or client_assertion'.
    // Explanation: this can happen if your application was not registered as a public client application in Azure AD
    // Mitigation: in the Azure portal, edit the manifest for your application and set the `allowPublicClient` to `true`
   }
   catch (MsalClientException ex)
   {
      // Error Code: unknown_user Message: Could not identify logged in user
      // Explanation: the library was unable to query the current Windows logged-in user or this user is not AD or AAD
      // joined (work-place joined users are not supported).

      // Mitigation 1: on UWP, check that the application has the following capabilities: Enterprise Authentication,
      // Private Networks (Client and Server), User Account Information

      // Mitigation 2: Implement your own logic to fetch the username (e.g. john@contoso.com) and use the
      // AcquireTokenByIntegratedWindowsAuth form that takes in the username

      // Error Code: integrated_windows_auth_not_supported_managed_user
      // Explanation: This method relies on a protocol exposed by Active Directory (AD). If a user was created in Azure
      // Active Directory without AD backing ("managed" user), this method will fail. Users created in AD and backed by
      // AAD ("federated" users) can benefit from this non-interactive method of authentication.
      // Mitigation: Use interactive authentication
   }
 }

 Console.WriteLine(result.Account.Username);
}

AcquireTokenByIntegratedWindowsAuthentication で使用可能な修飾子の一覧については、AcquireTokenByIntegratedWindowsAuthParameterBuilder に関する記事を参照してください。

次のステップ

このシナリオの次の記事である「デスクトップ アプリから Web API を呼び出す」に進みます。