Overview
What are we building today? We do have a Web APP API running in an Azure App Service that is protected with Azure Active Directory (AAD). We want to access this webservice from a PHP website. In our setup the php website runs in a local docker container. The first and foremost goal is to show how we can get hands on the access token from our PHP application.- Request the Index.php through http://localhost:90
- Use the OAuth2 library thenetworg/oauth2-azure to request an access token
- Authenticate against the app phpDemo in AAD and request access to ressource weatherapi
- Return the access token
- Return access token. Here you could call the web service with the returned bearer token
- Render the token on the website
- Use Postman to call the protected webservice
Creating the API-Application
Open Visual Studio 2019 and create a new „ASP.NET Core Web App“- Name: weatherapi
- Plattform: .NET Core / ASP.NET Core 3.1
- Template: API
- Azure
- Azure App Service (Windows)
- Select your subscription
- + Create a new Azure App Service …
- Name: weatherapi (select a unique name)
- Subscription: Your Subscription
- Resource Group: New… (phpdemo)
- Hosting Plan: New… (testplan)
-
- Click Create to create the Azure Resources
- Select the web app and click „Finish“
- Click Publish to publish the WebApp
Create AAD App for ASP.NET API with weather.read
- Open https://portal.azure.com
- Navigate to Azure Active Directory / App registrations
- + New registration
- Name: weatherapi
- Account Types: Single Tenant
- Redirect URI: Web – http://localhost:90
- Register
- Write down ClientID. In my case it is: b37*****b02
- Click on the button „Endpoints“
- Copy the „OpenID Connect metadata document“ Url. In my case: https://login.microsoftonline.com/e2****3d/v2.0/.well-known/openid-configuration where e2***3d is my tenant id.
- Copy the „OAuth 2.0 authorization endpoint (v2)“ https://login.microsoftonline.com/e2**3d/oauth2/v2.0/authorize
- Copy the „OAuth 2.0 token endpoint (v2)“ https://login.microsoftonline.com/e2**3d/oauth2/v2.0/token
- Navigate to Manage – Expose an API
- Application ID Uri (Set)
- You can use the given suggestion or define your own. In my case: api://b37******02
- Application ID Uri (Set)
- Navigate to Manage – Manifest
- Search for „accessTokenAcceptedVersion“ : null, and replace it with „accessTokenAcceptedVersion“ : 2, This will ensure that we receive OAuth 2.0 tokens! If you examine the JWT-Token in f.e. https://jwt.ms you will find the version set to: „ver“: „2.0“.
- Look out for „appRoles“: []
- Use GuidGen to create a new GUID (f.e. 4B****08)
- Insert the following:
"appRoles": [
{
"allowedMemberTypes": ["Application" ],
"description": "Weather API",
"displayName": "Weather API",
"id" : "4B*************08",
"isEnabled": true,
"lang" : null,
"origin": "Application",
"value": "weather.read"
}
],
Securing the API Application with Easy Auth
- Navigate to Azure App Services
- Select your weatherapi Application
- Under Settings click Authentication / Authorization
- Turn App Service Authentication ON
- In the drop down select „Log in with Azure Active Directory“
- Click „Azure Active Directory“
- Select Advanced
- Copy ClientID to Client ID field
- Copy „OpenID Connect metadata document“ to Issuer Url
- Click OK
- Save
Create AAD App for PHP Application
- Open https://portal.azure.com
- Navigate to Azure Active Directory / App registrations
- + New registration
- Name: phpdemo
- Account Types: Single Tenant
- Redirect URI: Web – http://localhost:90
- Register
- Write down ClientID. In my case it is: c9e*****9ea
- Click on the button „Endpoints“
- Copy the „OpenID Connect metadata document“ Url. In my case: https://login.microsoftonline.com/e2****3d/v2.0/.well-known/openid-configuration
- Click on Manage – Certificates & secrets
- + New client secret
- Name: mysecret
- Expiry: 2 Years
- Copy down the Secret (we need that later). In my case its: AKX**********
- + New client secret
- Click on Manager – API Permissions
- + Add a permission
- Select „My APIs“-Tab
- Select „weatherapi“
- Select „Application permissions“
- Select „weather.read“
- Add Permissions
- Note the orange exclamation sign! Use „Grant admin consent for…“ button next to „+ Add permission“ and confirm with Yes.
- + Add a permission
Creating the PHP Application
Since I did not want to install all PHP stuff on my machine I decided to develop my example in a docker container. Thanks to the TruthSeekers who wrote this excellent post on how to do exactly that. You can clone the source code here. After I cloned the git repository I had to adopt my docker-compose.yml file slightly since port 80 / 8080 are already consumed on my machine.... ports: - 90:80 ... ports: - 9090:8080 ...
Then I simply ran
-
docker-compose up -d
-
docker exec -it php-docker-simple_php_1 bash
apt-get update
apt-get install zip unzip
Cd ~
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '795f976fe0ebd8b75f26a6dd68f78fd3453ce79f32ecb33e7fd087d39bfeb978342fb73ac986cd4f54edd0dc902601dc') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
As OAuth2 library I want to use „thenetworg/oauth2-azure“ which can be found here.
It is based on the OAuth2 Library „thephpleague/oauth2-client“ which can be found here.
Then install this package to the sample which resides in /var/www/html:
cd /var/www/html php ~/composer.phar require thenetworg/oauth2-azureExit to the terminal and start VS-Code in the local directory or any other editor of your choice For our sample we need following information which we collected earlier:
- Client ID of the phpdemo app
- ClientSecret of the phpdemo app
- redirectUri of phpdemo app
- aad tenant id
- OAuth 2.0 Authorize Url
- OAuth 2.0 Token Url
- Client ID of the weatherapi app
$provider = new TheNetworg\OAuth2\Client\Provider\Azure([ 'clientId' => 'c9e*****9ea', 'clientSecret' => 'AKX********', 'redirectUri' => 'http://localhost:90', 'tenant' => 'e2*******3d', 'urlAuthorize' => 'https://login.microsoftonline.com/e2*******3d/oauth2/v2.0/authorize', 'urlAccessToken' => 'https://login.microsoftonline.com/e2*******3d/oauth2/v2.0/token', 'urlAPI' => 'b37*******b02', 'scope' => 'b37*******b02/.default' ]); $provider->defaultEndPointVersion = TheNetworg\OAuth2\Client\Provider\Azure::ENDPOINT_VERSION_2_0;We can now retrieve the access token with the following code:
$accessToken = $provider->getAccessToken('client_credentials', [
'scope'=> $provider->scope
]);
Here is the complete code of src/index.php to get and display the access token that we can then use to make a request to our api service:
<?php
echo "OAuth Sample<br/>";
/* Make sure we include necessary libraries */
require_once(__DIR__."/vendor/autoload.php");
/* Initialize provider */
$provider = new TheNetworg\OAuth2\Client\Provider\Azure([
'clientId' => 'c9e*****9ea',
'clientSecret' => 'AKX********',
'redirectUri' => 'http://localhost:90',
'tenant' => 'e2*******3d',
'urlAuthorize' => 'https://login.microsoftonline.com/e2*******3d/oauth2/v2.0/authorize',
'urlAccessToken' => 'https://login.microsoftonline.com/e2*******3d/oauth2/v2.0/token',
'urlAPI' => 'b37*******b02',
'scope' => 'b37*******b02/.default'
]);
$provider->defaultEndPointVersion = TheNetworg\OAuth2\Client\Provider\Azure::ENDPOINT_VERSION_2_0;
try {
$accessToken = $provider->getAccessToken('client_credentials', [
'scope' => $provider->scope
]);
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token
exit($e->getMessage());
}
echo "Access-Token:";
echo $accessToken;
Now we can call http://localhost:90 on our machine and retrieve the JWT Bearer Token.
Open Postman and make a get request to:
In the Authorization TAB select type: „Bearer Token“ and paste the access token to the token field.
If you hit Send now, you will retrieve the results of the weatherforecast.
That’s it. Thanks
Andreas

