Azure : Using PHP to go all oauth2 on the management API!


As a hobby effort, I wanted to create a small poc where any user would be able to login with their AAD user, grant access to an application, after which that application could query their subscriptions.

In all honesty, I’ve been struggling more than I like to admit with getting this working… So this post will cover all the steps that you need to do to get this working!


Oauth & Azure AD

Before getting our hands dirty, read up on the following post ; Authorize access to web applications using OAuth 2.0 and Azure Active Directory

Ready it thoroughly! To be honest, I didn’t at first and it cost me a lot of time. 😉

Anyhow, the flow looks as follows…


So basically;

  • We’ll redirect the user to sign-in (and if this hasn’t been done, grant our application access)
  • If all went well, we’ll receive an authorization code
  • We’ll use this code to get a bearer (and refresh) token
  • Next up we’ll use the bearer code to connect to the Azure REST API for getting the list of subscriptions for that user.


Prep on Azure AD

First start by creating a web application on Azure Active Directory. Be sure to set your reply url correct… AND (important) add “Windows Azure Service Management” as an additional application. Grant the delegated permission too.


Also be sure to set the application to “multi-tenant”.


And then generate your key… Be sure to note this down.


Just like with the client id!


Important ; Be aware that the key will include the applications you have added. So… if you changed the application permissions, then you will need to generate a new key!


Code Sample – Curl

Below you can find a quick & dirty code sample with just using curl…

ini_set('display_errors', 'On');

if (!isset($_GET['code'])) {
 $authUrl = "";
 $authUrl .= "client_id=your-client-id";
 $authUrl .= "&response_type=code";
 $authUrl .= "&";
 $authUrl .= "&response_mode=query";
 $authUrl .= "&";
 $authUrl .= "&state=12345";

 header('Location: '.$authUrl);

} else {

 $accesscode = $_GET['code'];

 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL,"");
 curl_setopt($ch, CURLOPT_POST, 1);
 $client_id = "your-client-id";
 $client_secret = "your-client-secret";
 curl_setopt($ch, CURLOPT_POSTFIELDS,
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 $server_output = curl_exec ($ch);
 curl_close ($ch); 
 $jsonoutput = json_decode($server_output, true);

 $bearertoken = $jsonoutput['access_token'];
 $url = "";
 $ch = curl_init($url);
 $User_Agent = 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31';
 $request_headers = array();
 $request_headers[] = 'User-Agent: '. $User_Agent;
 $request_headers[] = 'Accept: application/json';
 $request_headers[] = 'Authorization: Bearer '. $bearertoken;
 curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
 $result = curl_exec($ch);
 echo $result;


The most important things to note ;

  • We’ll be using “common” as tenant in the oauth authorize uri. This will ensure that this sample works for all tenants and not just a single one.
  • The redirect uri should map the one you configured in your application.
  • The resource should be included, where we’ll be using the “” to get a bearer token that applies to this target.
  • This code sample does not facilitate refresh tokens.


Code Sample – Oauth 2.0 Client

The following code sample is about the same, but this will leverage two libraries ;


require __DIR__ . '/vendor/autoload.php';

ini_set('display_errors', 'On');

$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
 'clientId' => 'your-client-id',
 'clientSecret' => 'your-client-secret',
 'redirectUri' => '',
 'resource' => ''

if (!isset($_GET['code'])) {

 // If we don't have an authorization code then get one
 $authUrl = $provider->getAuthorizationUrl();
 $_SESSION['oauth2state'] = $provider->getState();
 header('Location: '.$authUrl);

} else {

 // Try to get an access token (using the authorization code grant)
 $token = $provider->getAccessToken('authorization_code', [
 'code' => $_GET['code']

 $accesstoken = $provider->getAccessToken('refresh_token', [
 'refresh_token' => $token->getRefreshToken(),
 'resource' => ''

 $bearertoken = "Bearer " . $accesstoken->getToken();

 $client = new GuzzleHttp\Client([
 'base_uri' => '',
 'timeout' => 2.0,

 try {
 $result = $client->request('GET', "/subscriptions/?api-version=2015-01-01", [
 'headers' => [
 'User-Agent' => 'testing/1.0',
 'Accept' => 'application/json',
 'Authorization' => $bearertoken
 } catch (RequestException $e) {
 echo Psr7\str($e->getRequest());
 if ($e->hasResponse()) {
 echo Psr7\str($e->getResponse());
 echo $result->getBody();




Most important things to note here ;

  • Be sure to add the resource to the provide that covers the Azure API
  • All remarks from previous code also apply here… 😉



  • The oauth approach can provide you with a nice approach to act on behalf of a user.
  • Access tokens have a limited lifetime. This can be configured on tenant level. Which will be a balance between security & usability.
  • The common endpoint is used when you are looking for a multi tenant approach.

2 thoughts on “Azure : Using PHP to go all oauth2 on the management API!

  1. Hi,

    Many thanks for sharing the code but I’m getting resource error whenever I’m running your code.

    The below error I’m getting

    AADSTS650057: Invalid resource. The client has requested access to a resource which is not listed in the requested permissions in the client’s application registration. Client app ID: 2b3fae7c-932c-47d5-80d6-200d2b21cc7d(Arehman). Resource value from request: Resource app ID: 797f4846-ba00-4fd7-ba43-dac1f8f63013. List of valid resources from app registration: 00000003-0000-0000-c000-000000000000.

    Please help me I think it is related to Resource id

Leave a Reply

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

You are commenting using your 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

This site uses Akismet to reduce spam. Learn how your comment data is processed.