Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Unable to get a new refreshToken running from Azure functions .IdentityService and msal.cache missing #327

Closed
penicaudm opened this issue Jul 28, 2020 · 4 comments
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@penicaudm
Copy link

Steps to reproduce

Running a PowerShell Function in Azure functions. Similar to #234 the refreshtoken is always null because the msal.cache seems to be missing. Using the exact same values, I can get a new refreshToken from Azure Automation Runbooks or my local PowerShell console. Script can be found below

Expected behavior

New-PartnerAccessToken should return a new Refreshtoken using the given parameters.

Actual behavior

the returned object has no refreshToken. JSON sample below:

"RefreshToken": null,

Diagnostic logs

Script

# Input bindings are passed in via param block.
param($Timer)

# Get the current universal time in the default string format
$currentUTCtime = (Get-Date).ToUniversalTime()

# The 'IsPastDue' porperty is 'true' when the current function invocation is later than scheduled.
if ($Timer.IsPastDue) {
    Write-Host "PowerShell timer is running late!"
}

$AppID = $AppIDSecret.SecretValueText
$TenantID = $TenantIDSecret.SecretValueText
$refreshtoken = $refreshTokenSecret.SecretValueText

$PartnerAccessTokenSplat = @{
    Scopes        = 'https://api.partnercenter.microsoft.com/user_impersonation'
    ApplicationID = $AppID
    TenantID      = $tenantID
    RefreshToken  = $refreshtoken
}
Write-Output ($PartnerAccessTokenSplat | ConvertTo-Json)

$token = New-PartnerAccessToken @PartnerAccessTokenSplat

# https://github.com/microsoft/Partner-Center-PowerShell/issues/234
if($env:LOCALAPPDATA)
{
    $path = "$($env:LOCALAPPDATA)\.IdentityService"

    if(-not (Test-Path $path))
    {
        New-Item -Path "$path\msal.cache" -ErrorAction Stop -Force | Out-Null
    }
}
# debug tests

Test-Path (Join-Path -ChildPath Local\.IdentityService (Split-Path -Parent $env:LOCALAPPDATA) )
#returns false

Test-Path (Join-Path -ChildPath .IdentityService (Split-Path -Parent $env:LOCALAPPDATA) )
#returns false

Get-ChildItem -path (Join-Path -ChildPath Local\.IdentityService (Split-Path -Parent $env:LOCALAPPDATA))
#returns false

Get-ChildItem -path (Join-Path -ChildPath .IdentityService (Split-Path -Parent $env:LOCALAPPDATA))
#returns false

Test-Path (Join-Path -ChildPath Local\.IdentityService (Split-Path -Parent $env:APPDATA) )
#returns false
Test-Path (Join-Path -ChildPath .IdentityService (Split-Path -Parent $env:APPDATA) )
#returns false

# end debug tests

Write-Output ( $token | ConvertTo-Json )

Set-AzKeyVaultSecret -VaultName $KeyVaultName `
    -Name $refreshTokenSecret.Name `
    -SecretValue ($token.RefreshToken | ConvertTo-SecureString -AsPlainText -Force ) `
    -Expires ((get-date).AddDays(90))

# Write an information log with the current time.
Write-Host "PowerShell timer trigger function ran! TIME: $currentUTCtime"

Environment

Azure Functions
FUNCTION_WORKER_RUNTIME = Powershell
FUNCTION_EXTENSION_VERSION = 3

Requirements.psd1

# This file enables modules to be automatically managed by the Functions service.
# Only the Azure Az module is supported in preview.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{
    'Az' = '3.*'
    'PartnerCenter' = '3.*'
}
@xlZeroAccesslx
Copy link

@IsaiahWilliams I have the same issue. My script is a little different but works outside of Azure Functions. The Microsoft.Store.PartnerCenter.PowerShell.Models.Authentication.AuthResult object returned from New-PartnerAccessToken has a NULL refreshtoken attribute.

$token = New-PartnerAccessToken -ApplicationId $ApplicationId -Scopes 'https://api.partnercenter.microsoft.com/user_impersonation' -ServicePrincipal -Credential $credential -Tenant $TenantID -RefreshToken $RefreshToken

$token.refreshtoken is NULL

@ghost
Copy link

ghost commented Sep 1, 2020

@penicaudm and @xlZeroAccesslx this is an issue that you will see when using Azure Functions. Fortunately, you can resolve it by leveraging the Register-PartnerTokenCache command to change from a persistent token cache to an in-memory token cache. Note you will need to make sure the in-memory token cache is invoked at least once before using the New-PartnerAccessToken command.

Let us know if you have any other issues.

@ghost ghost self-assigned this Sep 1, 2020
@ghost ghost added good first issue Good for newcomers help wanted Extra attention is needed labels Sep 1, 2020
@xlZeroAccesslx
Copy link

xlZeroAccesslx commented Sep 1, 2020

Thanks @IsaiahWilliams . I invoked Register-PartnerTokenCache -InMemory before callingNew-PartnerAccessToken and received the error below. I restarted the App Service Plan to see if that would help. I'm using PowerShell Core 7.0. AZ and PartnerCenters are managed dependencies.

@{
    # For latest supported version, go to 'https://www.powershellgallery.com/package/Az'. 
    'Az' = '4.*'
    'PartnerCenter' = '3.*'
}

2020-09-01T04:31:40.689 [Error] ERROR: Could not find a part of the path 'C:\DWASFiles\Sites\<app-plan-name>\LocalAppData\.PartnerCenter\InMemoryTokenCache'.Exception :Type : System.IO.DirectoryNotFoundExceptionTargetSite :Name : ValidateFileHandleDeclaringType : System.IO.FileStreamMemberType : MethodModule : System.Private.CoreLib.dllStackTrace :at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)at System.IO.File.Create(String path)at Microsoft.Store.PartnerCenter.PowerShell.Commands.RegisterPartnerTokenCache.ExecuteCmdlet()at Microsoft.Store.PartnerCenter.PowerShell.Commands.PartnerPSCmdlet.ProcessRecord()Message : Could not find a part of the path 'C:\DWASFiles\Sites\<app-plan-name>\LocalAppData\.PartnerCenter\InMemoryTokenCache'.Source : System.Private.CoreLibHResult : -2147024893CategoryInfo : CloseError: (:) [Register-PartnerTokenCache], DirectoryNotFoundExceptionFullyQualifiedErrorId : Microsoft.Store.PartnerCenter.PowerShell.Commands.RegisterPartnerTokenCacheInvocationInfo :MyCommand : Register-PartnerTokenCacheScriptLineNumber : 31OffsetInLine : 1HistoryId : 1ScriptName : D:\home\site\wwwroot\<az-function-name>\run.ps1Line : Register-PartnerTokenCache -InMemoryPositionMessage : At D:\home\site\wwwroot\<az-function-name>\run.ps1:31 char:1+ Register-PartnerTokenCache -InMemory+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PSScriptRoot : D:\home\site\wwwroot\<az-function-name>PSCommandPath : D:\home\site\wwwroot\<az-function-name>\run.ps1InvocationName : Register-PartnerTokenCacheCommandOrigin : InternalScriptStackTrace : at <ScriptBlock>, D:\home\site\wwwroot\<az-function-name>\run.ps1: line 31PipelineIterationInfo :Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException : Result: ERROR: Could not find a part of the path 'C:\DWASFiles\Sites\<app-plan-name>\LocalAppData\.PartnerCenter\InMemoryTokenCache'.Exception :Type : System.IO.DirectoryNotFoundExceptionTargetSite :Name : ValidateFileHandleDeclaringType : System.IO.FileStreamMemberType : MethodModule : System.Private.CoreLib.dllStackTrace :at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)at System.IO.File.Create(String path)at Microsoft.Store.PartnerCenter.PowerShell.Commands.RegisterPartnerTokenCache.ExecuteCmdlet()at Microsoft.Store.PartnerCenter.PowerShell.Commands.PartnerPSCmdlet.ProcessRecord()Message : Could not find a part of the path 'C:\DWASFiles\Sites\<app-plan-name>\LocalAppData\.PartnerCenter\InMemoryTokenCache'.Source : System.Private.CoreLibHResult : -2147024893CategoryInfo : CloseError: (:) [Register-PartnerTokenCache], DirectoryNotFoundExceptionFullyQualifiedErrorId : Microsoft.Store.PartnerCenter.PowerShell.Commands.RegisterPartnerTokenCacheInvocationInfo :MyCommand : Register-PartnerTokenCacheScriptLineNumber : 31OffsetInLine : 1HistoryId : 1ScriptName : D:\home\site\wwwroot\<az-function-name>\run.ps1Line : Register-PartnerTokenCache -InMemoryPositionMessage : At D:\home\site\wwwroot\<az-function-name>\run.ps1:31 char:1+ Register-PartnerTokenCache -InMemory+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PSScriptRoot : D:\home\site\wwwroot\<az-function-name>PSCommandPath : D:\home\site\wwwroot\<az-function-name>\run.ps1InvocationName : Register-PartnerTokenCacheCommandOrigin : InternalScriptStackTrace : at <ScriptBlock>, D:\home\site\wwwroot\<az-function-name>\run.ps1: line 31PipelineIterationInfo :Exception: Could not find a part of the path 'C:\DWASFiles\Sites\<app-plan-name>\LocalAppData\.PartnerCenter\InMemoryTokenCache'.Stack: at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)at System.IO.File.Create(String path)at Microsoft.Store.PartnerCenter.PowerShell.Commands.RegisterPartnerTokenCache.ExecuteCmdlet()at Microsoft.Store.PartnerCenter.PowerShell.Commands.PartnerPSCmdlet.ProcessRecord()

@penicaudm
Copy link
Author

@IsaiahWilliams @xlZeroAccesslx Thanks, I added the command Register-PartnerTokenCache -InMemory at the start of my UpdateRefreshToken script and it works.

Running latest Az and PartnerCenter modules.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants