moving from ADAL to MSAL

I haven’t written a programming-related post in a while. I just had to rewrite some code that used ADAL to use MSAL, so I thought I’d write up a short post on that.

There’s a bunch of documentation around this on the Microsoft web site, but for the simple case I was interested in, it took some effort to track down.

Here are links to a couple of general articles:

What I needed was to rewrite a small block of code that calls a web API from a console app, with no user intervention. I have an Azure app registration set up to help with that, with a client ID and secret, and all that stuff. I have some links on how to set that up somewhere, but I’ll skip that for now.

The actual code I needed was something like the code here (to initialize MSAL) and here (to get a token). After I get the token, I just add it as a bearer token to the header for the request.

Here’s a bit of “before” and “after” code:

// before:
using Microsoft.IdentityModel.Clients.ActiveDirectory;

// get the parameters from a config file, or somewhere...
string clientId = ConfigurationManager.AppSettings["ClientId"];
string clientSecret = ConfigurationManager.AppSettings["ClientSecret"];
string authority = ConfigurationManager.AppSettings["Authority"];
string svcResourceId = ConfigurationManager.AppSettings["ServiceResourceId"];

AuthenticationContext authContext = null;
ClientCredential clientCredential = null;

authContext = new AuthenticationContext(authority);
clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationResult result = null;
try
{
	result = await authContext.AcquireTokenAsync(svcResourceId, clientCredential);
}
catch (AdalException ex)
{
	Console.WriteLine(String.Format(
		"An error occurred while acquiring a token\nTime: {0}\nError: {1}\n",
		DateTime.Now.ToString(), ex.ToString()));
	return;
}
//Console.WriteLine("Access Token: {0}", result.AccessToken);

client = new HttpClient();
client.BaseAddress = new Uri(BaseAddr);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Add the access token to the authorization header of the request.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

// after: 
using Microsoft.Identity.Client;

IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId)
	.WithClientSecret(clientSecret)
	.WithAuthority(authority)
	.Build();

AuthenticationResult authResult = null;
try
{
	List<String> scopes = new List<String>() { svcResourceId + "/.default" };
	authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();
	//string accessToken = authResult.AccessToken;
	//Console.WriteLine($"Access Token: {accessToken}");
}
catch (Exception ex)
{
	Console.WriteLine($"MSAL Error: {ex.Message}");
}

I’m not sure if anyone other than me will ever find this useful, but here it is, just in case.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.