Reputation: 12816
The Problem
MS Azure provides an extensive REST API. However, there is a significant amount of complexity when trying to get that API to work. From outdated and incomplete documentation to simple examples not working, performing what should be an easy task is instead nightmarish.
The Task
What are the exact, precise, detailed steps necessary to list the available VMs for someone who has logged in using Oauth2? For instance, this can be done using the azure-cli.
azure vm list
What are the steps to accomplish the same thing using REST and Oauth2?
The Requirements
The answer must not use Visual Studio, PowerShell, C#, an SDK, or any other such tool to accomplish this task. Only the portal is allowed for setup, and only Oauth2 is allowed for authorization, and only the REST API is allowed for actual information retrieval.
The answer must not simply link to external sources, although external references are encouraged for completeness.
The answer may assume the user has an Azure account. It must include information about creating the Oauth2 client, credentials, and any step necessary to get the appropriate token.
The answer must be detailed.
The answer must provide examples. Images, too are strongly encouraged.
The answer should include information about possible errors, their meanings, and what too look for to fix them.
Upvotes: 0
Views: 1477
Reputation: 12816
Making requests against the Azure Rest API is a bit more complicated than perhaps you would think at first glance. In particular, there are a number of esoteric and not-so-helpful error messages you may run into while getting the nobs tweaked just right.
One of the pieces of this process that can make it so confusing and difficult is the terminology. Until you understand that, knowing how to deal with errors is very difficult. We'll go over some of the more common ones here.
Subscription - This is basically what you'd expect. It refers to the Microsoft Azure Services subscription. It basically acts as the top-level umbrella for the organization.
Tenant - This is like a sub-organization, maybe a department or group. There can be multiple tenants under a single subscription.
User - As expected, a user is a single individual. Users are scoped to tenants.
Application - The Application is the software program trying to use the API. It must be registered and configured to do so.
Service Principal - This is essentially The Application. It is the entity making API Service requests.
Although you might not guess it, this is probably the most complicated part of the process. Let's start by creating The Application in the portal.
Follow this click path: Azure Active Directory -> App Registrations -> New
There should be a form for application creation, with the following fields:
API Tutorial
. This can be edited after creation.http://123AzureApiTutorial.com/code
. This can be edited after creation.Once the Application has been created, you should see a property, Application ID
. This is the client_id
used in the OAuth2 flow. Take a note of its value.
The OAuth2 flow requires a client secret value for authentication.
To generate it, follow this click path: Azure Active Directory -> App Registrations -> API Tutorial -> All Settings -> Keys
Enter the key description: API Tutorial Key
, and the Duration: In 1 year
.
Click Save
. This will generate the Key Value. You must copy the value here and save it somewhere. You will not have another opportunity to do so.
This value is the client_secret
in the OAuth2 flow.
To get to the permissions, follow this click path: Azure Active Directory -> App Registrations -> API Tutorial -> All Settings -> Required Permissions -> Add
Here you will see the list of possible APIs. The one we care about for Azure is Windows Azure Service Management API
. There is currently only one permission: Access Azure Service Management as organization users (preview)
. Select it, click Select
, and then Done
.
The access_token
is what allows us to make requests against the API. There are two primary ways to do this. I suggest reading about both before trying to implement them.
The authorization code is a two-step process. First we obtain the authorization code, and then we use that to get the access_token
. A benefit of this route is that we get back an id_token
as well, with a variety of useful claims like the user's name, email address, etc.
The request format is as follows: (GET) https://login.microsoftonline.com/<tenant-id>/oauth2/authorize?client_id=<client-id>&scope=api&redirect_uri=<redirect-uri>&response_type=code&prompt=consent
. Let's go over the parameters here really quick.
API Tutorial
. After the user logs in, they will be redirected to this URL with a "code" parameter in the query string.admin_consent
.Alright, so once we shoot off this request we will be redirected to the login page. We login, accept the permissions, and then we should be redirected to here: http://123AzureApiTutorial.com/code?code=SOME_REALLY_LONG_STRING_OF_CHARACTERS
. That string of characters is the code.
Next, we take the code and use it to get the access_token
. To do so, we need to make another request.
(POST) https://login.microsoftonline.com/<tenant-id>/oauth2/token
In addition to the url, we need to add parameters. These should be consistent with the content type application/x-www-form-urlencoded
. This means they are submitted as form parameters. They are as follows:
client_id
client_secret
code
SOME_REALLY_LONG_STRING_OF_CHARACTERS
.authorization_code
redirect_uri
http://123AzureApiTutorial.com/code
.resource
https://management.azure.com
.Our response will be a json object with a variety of fields. Of these, the one we care about is access_token. Yay!
This methodology skips getting the code (and thus needing the redirect_uri
) at the expense of not getting an id_token
.
The request is the same as in the Getting the Access Token section, with a few small differences.
redirect_uri
.client_credentials
.Alright, we have an access_token
! Now we're cooking!
With all the prep work thus far, this is the easiest part of the process.
The API URL we are requesting against is:
https://management.azure.com/subscriptions/<subscription-id>/providers/Microsoft.Compute/virtualMachines?api-version=2016-03-30
Add the following header to the request:
Authorization: Bearer <access-token>
. Yes, the access_token
value must be prefaced with the word "Bearer" in the header value.
"But wait!" You exclaim. "How do I get the subscription id?"
Excellent question! To find it through the portal, click Subscriptions -> -> Overview and copy the Subscription Id
value.
Use that value, and run the request. You should see all the vms listed!
InvalidAuthenticationToken
When making the API request, you get an error response that says something like this: InvalidAuthenticationToken: The access token is invalid
. This means you haven't added the API permissions to the API Tutorial
. Go back to the Add the correct permissions step and double-check you have the right permissions. Also, when requesting the token make sure you use the prompt=consent
, otherwise the you will not be prompted with the new permissions and the token will fail.
InvalidAuthenticationTokenTenant
Make sure that the tenant-id
used when requesting the token belongs to the subscriber used when making the API call.
Upvotes: 0
Reputation: 3293
First, we can find this rest API in azure resource portal. It is the same with Azure CLI command azure vm list
.
I have tested it on my local with http request. here is my tested screenshot:
Request URL: https://management.azure.com/subscriptions/<subscription ID>/providers/Microsoft.Compute/virtualMachines?api-version=2016-03-30
Header:Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI.....
So It is very import if we get the access token. The following demonstrate us how to get the access token.
Get Token(POST):
Request URL: https://login.microsoftonline.com/<tenant id>/oauth2/token
Body: grant_type=client_credentials&client_id=<client id>&resource=https%3A%2F%2Fmanagement.core.windows.net%2F&client_secret=<client secret>
Here is my screenshot in fildder:
We need to get client id and client secret in azure ad application. For how to regist an application in Azure AD. Please have a look at this article: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-service-principal-portal.
Please note:
1) we need to add "Windows Azure Service Management API" in portal "Required permissions" like the following screenshot: 2) We need assign "Contributor" for this service principal. click subscription-> Access Control-> click Add -> click "Select a Role" -> click Contributor->click Add User-> Find the application you created above-> click OK.
Upvotes: 1