【问题标题】:Xamarin Forms OAuth 2.0 and Azure Active Directory - error AdalServiceException: AADSTS7000218Xamarin Forms OAuth 2.0 和 Azure Active Directory - 错误 AdalServiceException: AADSTS7000218
【发布时间】:2019-08-21 03:02:43
【问题描述】:

我正在开发一个需要 AD 登录 + 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,对吗?

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

【问题讨论】:

  • 尝试编辑清单以将 allowPublicClients 设置为 true。请参阅README 步骤 5
  • 感谢 Max 的评论,我确实尝试了这种方法,但清单编辑器抱怨我的重定向 url 无效(我在身份验证选项卡中输入了重定向 url,但没有收到任何投诉)。我当时很困惑……我放弃了,没有再试一次。我相信你的方法也应该奏效。再次感谢!

标签: c# azure xamarin xamarin.forms oauth-2.0


【解决方案1】:

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

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

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

在这里,我为我的帐户实施了 MFA:

当我使用原生应用时,系统会要求我提供额外的验证。

【讨论】:

  • 感谢杰克的回答。我的公司采用了一种不同的方法,在 webview 中包含一个 web 版本的 AD 登录页面。但我相信你的方法也有效。再次感谢!
猜你喜欢
  • 2017-06-19
  • 1970-01-01
  • 2017-06-20
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2019-08-31
  • 2015-04-03
  • 1970-01-01
相关资源
最近更新 更多