调用 Web API 的桌面应用:使用集成窗口身份验证获取令牌
若要在域中或加入 Microsoft Entra 的计算机上登录域用户,请使用集成 Windows 身份验证 (IWA)。
约束
集成 Windows 身份验证仅可用于“联合 +”用户,即在 Active Directory 中创建并受 Microsoft Entra ID 支持的用户。 直接在 Microsoft Entra ID 中创建但不受 Active Directory 支持的用户(称为“托管”用户)不能使用此身份验证流。 此项限制不影响用户名和密码流。
IWA 不会绕过多重身份验证 (MFA)。 如果已配置 MFA,则在需要 MFA 质询的情况下,IWA 可能失败,因为 MFA 需要用户交互。
IWA 是非交互式的,但 MFA 需要用户交互。 标识提供者何时请求执行 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 门户中自行选择“授予”按钮。
- 或者,租户管理员已在应用程序注册的“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。