I was playing around with Azure API apps and the Azure Authentication / Authorization feature. I used this before when consuming API Apps in combination with Azure Web Apps that use SPN’s for the Web App to access the API App on behalf of the user. Let’s assume I have built a super cool API App and wanted to create a PowerShell module for that. I couldn’t get the PowerShell client to get a working token from the API App and after some searching and reaching out to the community I managed to get it working. Below I described the setup using the default Azure API app and consuming it using PowerShell.
First open Visual Studio and create a new project. (ASP.NET Web Application). Then choose Azure API App
Keep for the demo purpose the checkbox selected to deploy it to azure:
Create a new API app in Azure and click create:
If you are not a developer it might be a bit uncomfortable in this space, but what we created is actually an API App with 1 controller that when we run a Invoke-Restmethod -Method Get it wil do a HTTP Get against the ValuesController:
When we run that it should return a collection of strings in this case “value1” and “value2”. We will leave all defaults and publish this solution to our Web API App. Right click the project and choose publish:
Leave all default and click publish. Now we published our API App. Let’s play some simple PowerShell:
Run this command, change the URL for your API App and add /api/values. The /api is the routing policy for the API App and the values is the name of the controller you can refer to in your VS Solution. You see we get the 2 strings back from the API:
I mean, that was simple, now let’s add authentication using the Azure Authentication / Authorization. Open the Azure Portal and navigate to your API App, select the Authentication / Authorization and turn it on:
We need to select Azure Active Directory and create an Azure AD App:
Choose the proper name for you API App and click Ok and then Save. When you now go to the URL in your browser you get a login page or if you have SSO enabled for your tenant it will login automatically . When we run the PowerShell command again we get lots of html back in the console:
We need to create for PowerShell a native Azure AD Application and grant it permission on the API App. To enable this do the following. In the fancy old Azure Portal go to your Azure AD and click on applications. Then click on Add:
Choose Add application my organization is developing:
Choose native application and provide a name for your client:
For the return URL I used this:
urn:ietf:wg:oauth:2.0:oob
Click the check mark and take notice of the client Id:
The next step we need to do is allow the PowerShell Client APP to access the API app. Click on the configure tab and choose App Application:
Select your API App and click the checkmark. Select then the permission Access MySuperCoolAPI app and then click save.
Now let’s update our PowerShell to get an token and provide to the API to get our values again. I created a PowerShell function for the Token (Get-AADToken). Then I added some commands to get the token and invoke the rest method to the API App:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
function Get-AADToken { param ( [Parameter(Mandatory=$true)] $TenantName ) $adal = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" $adalforms = "${env:ProgramFiles(x86)}\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll" [System.Reflection.Assembly]::LoadFrom($adal) | Out-Null [System.Reflection.Assembly]::LoadFrom($adalforms) | Out-Null $clientId = "539e8a45-b940-465f-a782-c6239db43409" # = the Native Azure AD App Id $redirectUri = "urn:ietf:wg:oauth:2.0:oob" $resourceAppIdURI = "https://mysupercoolapi.azurewebsites.net" # Is the API App URI ID $authority = "https://login.microsoftonline.com/$TenantName" $authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority $authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto") return $authResult } $tenant = "markscholman.com" $token = Get-AADToken -TenantName $tenant $authHeader = @{ 'Content-Type'='application\json' 'Authorization'= $token.CreateAuthorizationHeader() } Invoke-RestMethod -Method Get -Uri 'http://mysupercoolapi.azurewebsites.net/api/values' -Headers $authHeader -UseBasicParsing |
And that’s it. Now I can retrieve values from my API App using Azure AD authentication using PowerShell!