呼叫 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 需要使用者互動。 您無法控制執行識別提供者要求 MFA 的時間,而租用戶系統管理員會這麼做。 從我們的觀察,當您從不同的國家/地區、未透過 VPN 連線到公司網路,有時甚至是透過 VPN 連線時,都需要 MFA。 請勿預期一組具決定性的規則。 Microsoft Entra ID 會使用 AI 來持續了解是否需要 MFA。 當 IWA 失敗時,切換回使用者提示,例如互動式驗證或裝置程式碼流程。
傳入
PublicClientApplicationBuilder
的授權單位必須是:https://login.microsoftonline.com/{tenant}/
表單的租用戶,其中tenant
是代表租用戶識別碼的 GUID,或與租用戶相關聯的網域。- 針對任何公司和學校帳戶:
https://login.microsoftonline.com/organizations/
。 - 不支援 Microsoft 個人帳戶。 您不能使用 /common 或 /consumers 租用戶。
因為整合式 Windows 驗證是無訊息流程:
- 您應用程式的使用者先前必須已同意才能使用應用程式。
- 或者,租用戶系統管理員先前必須已同意租用戶中的所有使用者,才能使用該應用程式。
- 換句話說:
- 您身為開發人員,請自行選取 Azure 入口網站中的 [授與] 按鈕。
- 或者,租用戶系統管理員已在應用程式註冊的 [API 權限] 索引標籤上,選取 [授與/撤銷 {租用戶網域} 系統管理員同意] 按鈕。 如需詳細資訊,請參閱新增存取 Web API 的權限。
- 或者,您已為使用者提供同意應用程式的方式。 如需詳細資訊,請參閱要求個別使用者同意。
- 或者,您也提供一種方法,讓租用戶系統管理員同意應用程式。 如需詳細資訊,請參閱管理員同意。
此流程已針對 .NET 傳統型、.NET 和 UWP 應用程式啟用。
如需有關同意的詳細資訊,請參閱 Microsoft 身分識別平台的權限和同意。
了解其使用方式
在 MSAL.NET 中,使用:
AcquireTokenByIntegratedWindowsAuth(IEnumerable<string> scopes)
您通常只需要一個參數 (scopes
)。 根據您 Windows 系統管理員設定原則的方式而定,您 Windows 電腦上的應用程式可能不允許查詢已登入的使用者。 在此情況下,請使用第二個方法 (.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。