title: Xamarin Forms OAuth 2.0 and Azure Active Directory - error AdalServiceException: AADSTS7000218
body: <p>I was developing a Xamarin Forms app that require AD Login + MFA to obtain a token from AD. So that my client app can call my WebAPI using this token and WebAPI side can verify this token against Azure before serving the client.</p>
  
  <p>I was using the NuGet extension Microsoft.IdentityModel.Clients.ActiveDirectory (v5.2.0) and the following is some related code for obtaining Azure token. </p>
  
  <pre class="lang-cs prettyprint-override"><code>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);
  </code></pre>
  
  <p>And I got the following error from Azure</p>
  
  <pre><code>{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 ---&gt; Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: Response status code does not indicate success: 401 (Unauthorized).
    at Microsoft.Identity.Core.OAuth2.OAuthClient+&lt;GetResponseAsync&gt;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+&lt;GetResponseAsync&gt;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+&lt;GetResponseAsync&gt;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+&lt;SendHttpMessageAsync&gt;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+&lt;SendTokenRequestAsync&gt;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+&lt;CheckAndAcquireTokenUsingBrokerAsync&gt;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+&lt;RunAsync&gt;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+&lt;AcquireTokenCommonAsync&gt;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+&lt;AcquireTokenAsync&gt;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+&lt;ADLogin&gt;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}
  </code></pre>
  
  <p>However if I use <code>ClientAssertion</code>, I won't be able to ask user to use username password login (is that correct?). So I am stuck here.</p>
  
  <p>Notes: </p>
  
  <ol>
  <li><p>I have actually tried another approach - create a WebAPI app and a native app in Azure app registration, that approach successfully obtain token but it doesn't trigger the MFA flow which my company need that as a security measure. </p></li>
  <li><p>I was told by other colleagues that native app doesn't support MFA, is that correct?</p></li>
  </ol>
  
  <p>Any comments or suggestions will be welcome. Thanks in advance!</p>