Problem:

An application receives the following error when authenticating to Azure Active Directory:

{
     “error”: “invalid_client”,

     “error_description”: “AADSTS7000218: The request body must contain the following parameter: ‘client_assertion’ or ‘client_secret’.\r\nTrace ID: xxx\r\nCorrelation ID: xxx\r\nTimestamp: 2019-08-18 20:38:28Z”,

     “error_codes”: [7000218],

     …

}

What does this error mean?

The error is what it said.  When authenticating to Azure AD to get an access token, the client application is not providing its “password” (in the form of either a client secret or a client assertion) as expected by Azure AD’s token endpoint.  Before diving into this error, let’s spend a few minutes understanding the context of the issue.  As defined in the OAuth2 specifications, there are 2 types of client applications:

  • Confidential Client – a client who is capable of storing a secret (used to authenticate to Azure AD).  An example of this client is a web application, where its code and secret are stored on the server that’s not exposed to the public.  The application’s confidential information can only be accessed by an admin person.
  • Public Client – as you guess,  a client not capable of storing any secret.  An example of a public client is a mobile application or a desktop application running at public kiosk in an insecure and unmanaged environment.

A confidential client is always expected to provide its credential (client secret or assertion) when authenticating to Azure AD.

So how does Azure AD know if the authenticating client is public or confidential?

In most cases, Azure AD looks at the reply / redirect URL provided in the request and cross check it with the reply URL registered in Azure AD’s App Registration blade find out the type (see screen shot below).  A ‘Web’ type is Confidential client and the ‘Public client (mobile & desktop)’ type is a Public client

In certain OAuth2 authentication flows such as OAuth2 resource owner password credentials (ROPC) grant flow, OAuth2 device code flow, and Integrated Windows Authentication, there is no reply URL provided in the token request.  In such case,  Azure AD looks at the app registration’s default type (see screen shot below) to determine if the client is confidential or public.

If “yes’ is selected, it’s a public client.  ‘No’ is a confidential client.

Yes in the current Azure AD’s App Registration model, a registered application can be both a public client and a confidential client, depending on the context the application is used in.  This is because an application may have part of it used as a public client while some other parts are designed to be used as a confidential client.  Depending on certain workflows the application developer must decide if the application should act as public or confidential client.

A Confidential client is expected in certain OAuth2 grant flows

Client Credentials flow, Authorization Code flow, and On-Behalf-Of flow are used by Confidential client to request a token.  Azure AD will return the above error if the request is missing a client secret or a client assertion.

How do I know which grant type and what redirect URL (if any) my application is using?

Review your application code or take a Fiddler trace to see what the ‘grant_type’ parameter and what ‘redirect_uri’ parameter are sent in the POST request to Azure AD’s token end point: https://login.microsoftonline.com/<tenant name>/oauth2/token (V1 endpoint) or https://login.microsoftonline.com/<tenant name>/oauth2/v2.0/token (V2 endpoint).

Refer to the table below for more information on grant type and oauth2 flow:

OAuth2 flow

grant_type value

ROPC

password

Device code

urn:ietf:params:oauth:grant-type:device_code

Authorization Code

authorization_code

Client Credentials

client_credentials

On-Behalf-Of

urn:ietf:params:oauth:grant-type:jwt-bearer

SAML Bearer Assertion

urn:ietf:params:oauth:grant-type:saml1_1-bearer

So what’s the resolution?

By now you probably figure this out that if the application is expected to be a Confidential client then provide the client secret or assertion.  In some authentication flow scenario like ROPC or Device Code flow where you don’t expect the client application to be confidential, follow the steps below to change the default type to Public client.

  1. Go to the App Registration for this application
  2. Select “Authentication” – > tick ‘Yes’ for Default client type -> Save the change

Reference

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-Applications

Leave a Reply

avatar
  Subscribe  
Notify of