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:
- Migrate applications to the Microsoft Authentication Library (MSAL)
- Differences between ADAL.NET and MSAL.NET apps
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.