MSEndpointMgr / IntuneWin32App

Provides a set of functions to manage all aspects of Win32 apps in Microsoft Intune.
MIT License
340 stars 88 forks source link

WARNING: An error occurred while attempting to retrieve or refresh access token. Error message: Could not use the certificate for signing #170

Open Ka1Nn opened 4 weeks ago

Ka1Nn commented 4 weeks ago

Hello guys,

I'm using a corporate user certficate for connecting to graph : $Cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.Issuer.StartsWith("CN=Blabla") } Connect-MSIntuneGraph -TenantId $TenantId -ClientId $AppId -ClientCert $Cert

However, I'm receiving the following error: WARNING: An error occurred while attempting to retrieve or refresh access token. Error message: Could not use the certificate for signing. See inner exception for details. Possible cause: this may be a known issue with apps build against .NET Desktop 4.6 or lower. Either target a higher version of .NET desktop - 4.6.1 and above, or use a different certificate type (non-CNG) or sign your own assertion as described at https://aka.ms/msal-net-signed-assertion.

I'm able to connect to my Service Principal ( app permissions ) with : Connect-MgGraph -TenantId $TenantId -ClientId $AppId -Certificate $Cert or using a ClientSecret Connect-MSIntuneGraph -TenantID $TenantID -ClientID $ApplicationId -ClientSecret $SecuredPass Connect-MgGraph -TenantId $TenantId -ClientSecretCredential $SecuredPass

For security reasons, our Security Officer prohibits the use of Client Secret. We are required to use only our company-issued user certificates.. While I have no issues connecting with Connect-MgGraph, I am unable to connect using Connect-MSIntuneGraph with the certificate.

How i can get a refresh token to pass through to the global variable AuthenticationHeader or how can i connect with the IntuneWin32App module ( Connect-MSIntuneGraph ). Of course the usage for self sign certificat is also not allowed..

Thank you for your help

Ka1Nn commented 3 weeks ago

I've just solved the issue.

Solution N°1 : I'm still using Powershell 5.1, so i found a workaround that involves retrieving the Secret from the In-Memory Token Cache

$TenantID = '<tenantID>'
$AppId     = '<ClientID>'

# Retrieve the certificate and connect to Microsoft Graph
$Cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.Issuer.StartsWith("blabla") }
Connect-MgGraph -TenantId $TenantId -ClientId $AppId -Certificate $Cert

# Get the method to retrieve the token data and extract it
$InMemoryTokenCacheGetTokenData = [Microsoft.Graph.PowerShell.Authentication.Core.TokenCache.InMemoryTokenCache].GetMethod("ReadTokenData", [System.Reflection.BindingFlags]::NonPublic + [System.Reflection.BindingFlags]::Instance)
$TokenData = $InMemoryTokenCacheGetTokenData.Invoke([Microsoft.Graph.PowerShell.Authentication.GraphSession]::Instance.InMemoryTokenCache, $null)

# Convert token data to UTF-8 string and parse JSON
$utf8Token = [System.Text.Encoding]::UTF8.GetString($TokenData)
$parsedTokenData = $utf8Token | ConvertFrom-Json

# Extract the access token and expiration date
$Global:AccessToken = $parsedTokenData.AccessToken."-login.windows.net-accesstoken-$AppId-$TenantID-https://graph.microsoft.com/.default"

# Construct the authentication header
$Global:AuthenticationHeader = @{
    "Content-Type"  = "application/json"
    "Authorization" = "bearer $($accessToken.secret)"
    "ExpiresOn"     = [System.DateTimeOffset]::FromUnixTimeSeconds($accessToken.expires_on).ToUniversalTime().UtcDateTime

}

# Output the constructed header for verification
Write-Output $AuthenticationHeader

You also need to modify the Test-AccessToken script Replace the existing line with :
$TokenExpireMinutes = [System.Math]::Round(([System.DateTimeOffset]::FromUnixTimeSeconds($accessToken.expires_on).ToUniversalTime().UtcDateTime - $UTCDateTime).TotalMinutes)

Solution N°2 : Use Powershell 7.x MSAL is too much limited with Powershell 5.1

Hope it will help

obuolinis commented 3 weeks ago

Jesus, this looks like an one ugly workaround :) I also encountered this same issue when using a self-signed cert on Powershell 5.1. Upon investigation I found this, you can find some ideas there: https://github.com/AzureAD/MSAL.PS/issues/15 However my workaround was to just switch to Powershell v7.

Ka1Nn commented 3 weeks ago

Thanks for the feedback! 😅 I agree, it's not the prettiest workaround, but it works in my context. I've already check the thread https://github.com/AzureAD/MSAL.PS/issues/15, which is how i found the Solution N°2.