简体   繁体   中英

Xamarin Forms OAuth 2.0 and Azure Active Directory - error AdalServiceException: AADSTS7000218

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.

I was using the NuGet extension Microsoft.IdentityModel.Clients.ActiveDirectory (v5.2.0) and the following is some related code for obtaining Azure token.

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);

And I got the following error from 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}

However if I use ClientAssertion , I won't be able to ask user to use username password login (is that correct?). So I am stuck here.

Notes:

  1. 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.

  2. I was told by other colleagues that native app doesn't support MFA, is that correct?

Any comments or suggestions will be welcome. Thanks in advance!

In oauth2-auth-code-flow , the client secret parameter is required for web apps.

在此处输入图片说明

So, you need to add a public client (native) platform.

在此处输入图片说明

For the MFA issue, if you apply MFA via Azure Conditional Access Policy , it will apply multifactor authentication on modern app supported clients. Native clients might bypass MFA. But if you enforce MFA (via AzureAD MFA setting) it will enforce Multi factor authentication for all requests.

Here, I enforced MFA for my account: 在此处输入图片说明

When I use the native app, I will be asked to provide additional verification.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM