首页 > 解决方案 > Xamarin Forms OAuth 2.0 和 Azure Active Directory - 错误 AdalServiceException: AADSTS7000218

问题描述

我正在开发一个需要 AD Login + MFA 才能从 AD 获取令牌的 Xamarin Forms 应用程序。这样我的客户端应用程序就可以使用此令牌调用我的 WebAPI,并且 WebAPI 端可以在为客户端提供服务之前针对 Azure 验证此令牌。

我使用的是 NuGet 扩展 Microsoft.IdentityModel.Clients.ActiveDirectory (v5.2.0),以下是获取 Azure 令牌的一些相关代码。

private static string aadInstance = "https://login.microsoftonline.com/{0}";
private static string tenant = "MY_TENANT_GUID";
private static string clientId = "MY_CLIENT_GUID";
private static Uri redirectUri = new Uri("MY_CLIENT_WEB_REDIRECT_URL");
private static string resourceId = "MY_CLIENT_GUID";
private static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);

...

//the line that try to get Azure token...
authContext = new AuthenticationContext(authority);
authResult = await authContext.AcquireTokenAsync(resourceId, clientId, redirectUri, platformParameters);

我从 Azure 收到以下错误

{Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
Trace ID: ec487fae-628e-4c0a-a174-634f962e1000
Correlation ID: 3db513fc-79ca-417c-b0af-e34c112e77a8
Timestamp: 2019-08-21 02:26:05Z ---> Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: Response status code does not indicate success: 401 (Unauthorized).
  at Microsoft.Identity.Core.OAuth2.OAuthClient+<GetResponseAsync>d__18`1[T].MoveNext () [0x00108] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Core\OAuth2\OAuthClient.cs:66 
   --- End of inner exception stack trace ---
  at Microsoft.Identity.Core.OAuth2.OAuthClient+<GetResponseAsync>d__18`1[T].MoveNext () [0x00334] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Core\OAuth2\OAuthClient.cs:116 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.Identity.Core.OAuth2.OAuthClient+<GetResponseAsync>d__17`1[T].MoveNext () [0x00028] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Core\OAuth2\OAuthClient.cs:45 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase+<SendHttpMessageAsync>d__75.MoveNext () [0x00053] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Internal\Flows\AcquireTokenHandlerBase.cs:405 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase+<SendTokenRequestAsync>d__72.MoveNext () [0x00052] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Internal\Flows\AcquireTokenHandlerBase.cs:333 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase+<CheckAndAcquireTokenUsingBrokerAsync>d__62.MoveNext () [0x000f5] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Internal\Flows\AcquireTokenHandlerBase.cs:266 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.Internal.Flows.AcquireTokenHandlerBase+<RunAsync>d__60.MoveNext () [0x0070e] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\Internal\Flows\AcquireTokenHandlerBase.cs:241 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext+<AcquireTokenCommonAsync>d__42.MoveNext () [0x000a1] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\AuthenticationContext.cs:608 
--- End of stack trace from previous location where exception was thrown ---
  at Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext+<AcquireTokenAsync>d__32.MoveNext () [0x00047] in D:\a\1\s\src\Microsoft.IdentityModel.Clients.ActiveDirectory\AuthenticationContext.cs:407 
--- End of stack trace from previous location where exception was thrown ---
  at ADM.Services.ADService+<ADLogin>d__8.MoveNext () [0x001b1] in C:\Users\[User]\Desktop\Source\[My App]\400 Implementation\ADM\ADM\ADM\Services\ADService.cs:83 
    ErrorCode: invalid_client
    StatusCode: 401}

但是,如果我使用ClientAssertion,我将无法要求用户使用用户名密码登录(正确吗?)。所以我被困在这里。

笔记:

  1. 我实际上尝试了另一种方法 - 在 Azure 应用程序注册中创建一个 WebAPI 应用程序和一个本机应用程序,该方法成功获取令牌,但它不会触发我的公司需要的 MFA 流作为安全措施。

  2. 其他同事告诉我,原生应用程序不支持 MFA,对吗?

欢迎任何意见或建议。提前致谢!

标签: c#azurexamarinxamarin.formsoauth-2.0

解决方案


oauth2-auth-code-flow中,Web 应用程序需要客户端密码参数。

在此处输入图像描述

因此,您需要添加一个公共客户端(本机)平台。

在此处输入图像描述

对于 MFA 问题,如果您通过 Azure 条件访问策略应用 MFA,它将在现代应用支持的客户端上应用多因素身份验证。本机客户端可能会绕过 MFA。但是,如果您强制执行 MFA(通过 AzureAD MFA 设置),它将对所有请求强制执行多因素身份验证。

在这里,我为我的帐户实施了 MFA: 在此处输入图像描述

当我使用本机应用程序时,系统会要求我提供额外的验证。


推荐阅读