0

I am trying to automate downloading of Azure Consumption info using REST API.
I modified sample that returns list of subscriptions.
I changed the url and I added couple of additional parameters.

import adal
import requests

authentication_endpoint = 'https://login.microsoftonline.com/'
resource  = 'https://management.core.windows.net/'
application_id = '4c681786-980d-44cb-89f9-123456789012'
application_secret = 'xxxxxxxxxxxxxxxxxxxxxxx'
tenant_id = 'xxxxxxxxx-xxxx-xxxx-xxxx-123456789012'
enrollmentNumber = 'XXXXXXXX'

# get an Azure access token using the adal library
context = adal.AuthenticationContext(authentication_endpoint + tenant_id)
token_response = context.acquire_token_with_client_credentials(resource, application_id, application_secret)

access_token = token_response.get('accessToken')

# endpoint = 'https://management.azure.com/subscriptions/?api-version=2015-01-01'
scope = '/providers/Microsoft.Billing/enrollmentAccounts/' + enrollmentNumber
endpoint = 'https://management.azure.com' + scope + '/providers/Microsoft.Consumption/usageDetails?api-version=2019-10-01'

headers = {"Authorization": 'Bearer ' + access_token}
json_output = requests.get(endpoint,headers=headers).json()
print(json_output)

Instead of json with consumption info I am getting an error:

Puid is null/empty. Puid must be present in the header for user to get authorized.

With the same token, I can get list of all subscriptions.

DejanS
  • 96
  • 9

1 Answers1

0

I have reviewed your request and based on findings, please note that PUID is an attribute specific for user objects and service principals in Azure AD do not have a PUIDs. However, the billing platform most likely needs a PUID of a user that is entitled to read the billing data.

the following headers are needed.

x-ms-client-tenant-id :
x-ms-client-object-id :
x-ms-client-principal-id:

Which clients cannot set these headers. When they make ARM call, these headers get set by system. The fact that error says that this header is missing, it means that the call is being made in context of an App (AAD app or service prinicipal). This is at present not supported for management group scope.

I would suggest you to try using the management api using User Credential .

Or alternatively you have to use Native client application in you azure AAD tenant to access billing api's, for further information please check the below link:

https://github.com/Azure-Samples/billing-dotnet-usage-api#step-1-configure-a-native-client-application-in-your-aad-tenant

Hope it helps.

Mohit Verma
  • 5,140
  • 2
  • 12
  • 27
  • I am a user that is allowed to see that data. For example, I can manually download Cost Management + Billing - Usage + charges like "Usage Details Version 2". I can also go in the Enterprise Agreement https://ea.azure.com/ and download usage info manually there. I thought that by using token (adding it to request) I am getting identified as someone who has access. – DejanS Dec 03 '19 at 14:56
  • Actually, code above is using application that I registered on AAD and secret to authenticate the app. – DejanS Dec 03 '19 at 15:17