I’ve recently been working on a project to display Azure billing information in an internal dashboard and to send out alerts if the billing exceeds a certain amount.

The first problem I had with this was that although there’s GitHub projects for getting the rate card and billing information they’re not built in ASP.NET Core and they use an older version of the package Microsoft.IdentityModel.Clients.ActiveDirectory. I still haven’t figured out how to get it working with individual user accounts which authenticate through a Microsoft login form but below is an explanation of how to authenticate using a client ID and Secret which is sufficent for my purposes.

Authentication

Below is the basic code for retrieving a token from Azure AAD, one think to note is that v1.1.1 of Microsoft.NETCore.App and v3.13.9 of Microsoft.IdentityModel.Clients.ActiveDirectory are being used.

using AzureBillingNotificationEmail.Helpers;
using AzureBillingNotificationEmail.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace AzureBillingNotificationEmail
{
	public class Program
	{
		// This is the ID of the client being used to access the AAD, it can be found as Application ID under Azure Active Directory > App registrations > YOUR_APP_NAME
		// This app is created as part of the process in https://github.com/Azure-Samples/billing-dotnet-ratecard-api
		private static string clientId = "";
		// This is the key for the client ID above, it can be found as Application ID under Azure Active Directory > App registrations > YOUR_APP_NAME > Keys
		// This key is only visible when first created so make sure you note it down then!
		private static string clientSecret = "";
		// This is the ID of the AAD to be accessed, it can be found as Directory ID under Properties in the Azure Active Directory Blade in the portal
		private static string tennantId = "";
		private static string resource = "https://management.core.windows.net/";
		private static string authority = "https://login.windows.net";
		private static string billingService = "https://management.azure.com";
		// This is the ID of the subscription that you want to view billing information for, it can be found in the Subscriptions blade of the portal
		private static string subscriptionId = "";
		
		public static void Main(string[] args)
		{
			string token = GetOAuthTokenFromAAD(clientId, clientSecret, tennantId, resource, authority).Result;
		}
		
		public static async Task GetOAuthTokenFromAAD(string clientId, string clientSecret, string tenantId, string resource, string authority)
		{
			ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
			AuthenticationContext authenticationContext = new AuthenticationContext(String.Format("{0}/{1}", authority, tenantId));
			AuthenticationResult result = await authenticationContext.AcquireTokenAsync(resource, clientCredential);
			
			if (result == null)
			{
				throw new InvalidOperationException("Failed to obtain the JWT token");
			}
			
			return result.AccessToken;
		}
	}
}

This token can then be used to query the Rate Card and Billing APIs, an example of this in action can be seen in this project.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *