Connect to Microsoft Graph using MSAL and Certificate based Authentication

I had a recently gotten some question’s on how to connect to Microsoft GraphApi using certificate instead of an app secret. I have set this up before using the Microsoft Graph PowerShell SDK but I wanted to test this using Invoke-RestMethod.

There is a PowerShell module that has been created that allow for much easier creation of authentication tokens using Microsoft Authentication Library.

Learn about MSAL – Microsoft identity platform | Microsoft Docs

The Microsoft Authentication Library (MSAL) enables developers to acquire tokens from the Microsoft identity platform in order to authenticate users and access secured web APIs. It can be used to provide secure access to Microsoft Graph, other Microsoft APIs, third-party web APIs, or your own web API. MSAL supports many different application architectures and platforms including .NET, JavaScript, Java, Python, Android, and iOS.

MSAL gives you many ways to get tokens, with a consistent API for a number of platforms. Using MSAL provides the following benefits:

  • No need to directly use the OAuth libraries or code against the protocol in your application.
  • Acquires tokens on behalf of a user or on behalf of an application (when applicable to the platform).
  • Maintains a token cache and refreshes tokens for you when they are close to expire. You don’t need to handle token expiration on your own.
  • Helps you specify which audience you want your application to sign in (your org, several orgs, work, and school and Microsoft personal accounts, social identities with Azure AD B2C, users in sovereign, and national clouds).
  • Helps you set up your application from configuration files.
  • Helps you troubleshoot your app by exposing actionable exceptions, logging, and telemetry.

The PowerShell module that can be used to create tokens is called MSAL.PS and the latest version as of today is 4.21.0.1.

PowerShell Gallery | MSAL.PS 4.21.0.1

In this post we will be going through installing and using this module to generate an authentication token using a self signed certificate and using that token to connect to Microsoft Gaph.

The first step is to install the MSAL.PS module

Once the module is installed we can generate the certificate that will be used to connect to Microsoft Graph

To create the self signed cert I used the below command. There was a error when trying to generated the token when I didn’t use -KeySpec when generating the cert. The fix to use -KeySpec was on the GitHub issue page.

Get-MsalToken with Client Certificate fails on Windows PowerShell 5.1 · Issue #15 · AzureAD/MSAL.PS (github.com)

New-SelfSignedCertificate -DnsName TennatDomainName -CertStoreLocation "Cert:\CurrentUser\My" -FriendlyName "MSAL_Cert" -KeySpec Signature

Once the cert has been created, export the cert so that it can be uploaded to the App registration.

Get-ChildItem Cert:\CurrentUser\my\CertThumbprint | Export-Certificate -FilePath C:\temp\Graph_MSAL_Cert.cer

Once the cert is exported we can upload to the app registration that we created before. See previous post if app registration hasn’t been created in Azure yet for Microsoft Graph.

Connecting to Microsoft GraphAPI Using PowerShell – TheSleepyAdmins

To add the cert open the Azure portal > Azure Active Directory >  App registrations and select the Graph app and go to certificates & secrets

Select upload certificate

Click add to apply the cert

After the cert is upload we should now be able to connect. We will need the TenantId, clientId and certificate

The tenantID and ClientId can be gotten from the app registration overview page and the cert can be gotten using Get-Item and the cert location / thumbprint.

Import-Module MSAL.PS
$TenantId = "TenantId"
$ClientId = "ClientId" 
$ClientCert = Get-ChildItem "Cert:\CurrentUser\my\CertThumbprint"
$MSToken = Get-MsalToken -ClientId $ClientId -TenantId $TenantId -ClientCertificate $ClientCert

If you want to use the same cert for any users on the device we can export and import the cert under localmachine cert store with the private key and update the $clientCert to use localmachine instead of currentuser.

Get-Item "Cert:\localmachine\my\CertThumbprint"

Once we have the token, it’s now the same process as we have used before to connect using invoke-restmethod but using the $MSToken.AccessToken we generated using the Get-MsalToken and our certificate.

$GraphGroupUrl = 'https://graph.microsoft.com/v1.0/Groups/'
(Invoke-RestMethod -Headers @{Authorization = "Bearer $($MSToken.AccessToken)"} -Uri $GraphGroupUrl -Method Get).value.displayName

Using MSAL.PS module provides a much quicker and easier way to generate access tokens for Microsoft Graph with the added security of using a certificate over having to put in any application secret.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s