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.