Sign in with App ID and App Secret

Posted by

Knowing the application secret of an Azure AD registered application allows for an interactive sign-in using the client credentials grant. The application ID corresponds to the user name and the application secret corresponds to the password, which is why the secret is also called the application password. If the registered application is a multi-tenant application, such a sign-in is possible in every tenant where consent was given for the application. The access token received from the sign-in can then be used in Microsoft Graph API calls made possible through application permissions.

For example, there is an application registered named jmprieur-dotnet-web-daemon-v2 with

  • tenant where application is registered: 8b3c36dd-942d-4ea7-a4dd-df9ef430cf5a
  • application ID: 5fdb1e39-be38-4cb1-8523-9d97365ed7de
  • application secret: li.t14-00uhd9Ji~5a2a647D_h68F6sx11
  • tenant where consent is given for application: 9cbada80-ca8c-43b1-8fb2-492cf58bccc9


The application has two delegated permissions and one application permission set up.

Microsoft recommends using an authentication library (like MSAL) for Azure AD authentication scenarios. Ignoring that, a simple HTTP POST request also gets an access token.
$postParams = @{
    client_id='5fdb1e39-be38-4cb1-8523-9d97365ed7de';
    client_secret='li.t14-00uhd9Ji~5a2a647D_h68F6sx11';
    scope='https://graph.microsoft.com/.default';
    grant_type='client_credentials'}
$accessToken = ((Invoke-WebRequest -Uri https://login.microsoftonline.com/9cbada80-ca8c-43b1-8fb2-492cf58bccc9/oauth2/v2.0/token -Method POST -Body $postParams).Content | ConvertFrom-Json).access_token

Note that the ‘scope’ parameter is required. Specifying ‘.default’ returns an access token that contains all application permissions. In the example it looks like this:


It can be seen that the access token contains the one application permission, but none of the delegation permissions. Consequently, in this example, the access token cannot be used to read a user’s mail, but it can be used to read all properties of all Azure AD accounts.

The manager of user ryan@resource-tenant.com can be found with the following REST call:
Invoke-RestMethod -Uri 'https://graph.microsoft.com/v1.0/users/ryan@resource-tenant.com/manager' -Headers @{'Authorization' = "Bearer " + $accessToken} -Method Get

This blog post is a small add-on to Jan Geisbauer‘s Privilege escalation in Azure AD article.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s