You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MSAL库配合PowerShell获取Azure DevOps令牌跨会话缓存失效问题

问题根本原因

MSAL.NET 默认将令牌缓存在当前进程的内存中,PowerShell 会话结束后内存缓存会被完全释放,因此重新打开会话后无法读取到之前的登录凭证,必须重新走交互式登录流程。

解决方案:配置MSAL持久化令牌缓存

你需要引入MSAL官方的缓存扩展组件,将令牌缓存加密存储到本地磁盘,实现跨PowerShell会话共享。

第一步:安装依赖组件

先安装MSAL缓存扩展的NuGet包:

Install-Package Microsoft.Identity.Client.Extensions.Msal -Scope CurrentUser

第二步:修改你的脚本,启用持久化缓存

修改后的完整可运行代码如下:

# 请替换为你自己的配置
$ClientId = "你的Azure AD应用注册客户端ID"
$adoResourceId = "499b84ac-1321-427f-aa17-267ca6975798" # Azure DevOps官方资源ID固定为这个值
[string[]] $Scopes = "$adoResourceId/.default"

# 配置持久化缓存参数
$cacheDir = Join-Path $env:USERPROFILE ".msal_cache"
$cacheFileName = "ado_msal_cache.bin"
if (-not (Test-Path $cacheDir)) { New-Item -ItemType Directory -Path $cacheDir | Out-Null }

# 初始化缓存助手,自动处理加密存储(Windows用DPAPI,macOS用钥匙串,Linux用libsecret)
$storageProperties = [Microsoft.Identity.Client.Extensions.Msal.StorageCreationPropertiesBuilder]::new($cacheFileName, $cacheDir).Build()
$cacheHelper = [Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper]::CreateAsync($storageProperties).GetAwaiter().GetResult()

# 构建公共客户端应用,挂载持久化缓存
[Microsoft.Identity.Client.IPublicClientApplication] $app = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($ClientId).Build()
$cacheHelper.RegisterCache($app.UserTokenCache)

# 获取缓存中的账户
[ContextHelper]::Account = $app.GetAccountsAsync().GetAwaiter().GetResult() | Select-Object -First 1
$tokenSource = New-Object System.Threading.CancellationTokenSource
$taskAuthenticationResult = $null
$result = $null

try {
    # 优先静默获取令牌
    $AquireTokenParameters = $app.AcquireTokenSilent($Scopes, [ContextHelper]::Account)
    $taskAuthenticationResult = $AquireTokenParameters.ExecuteAsync($tokenSource.Token)
    $taskAuthenticationResult.Wait()
    $result = $taskAuthenticationResult.Result
}
catch {
    # 静默失败则走交互式登录
    $AquireTokenParameters = $app.AcquireTokenInteractive($Scopes)
    $taskAuthenticationResult = $AquireTokenParameters.ExecuteAsync($tokenSource.Token)
    $taskAuthenticationResult.Wait()
    $result = $taskAuthenticationResult.Result
}

# 输出令牌结果
Write-Host "获取到的访问令牌有效期至:$($result.ExpiresOn)"
注意事项
  • 本地缓存文件默认采用当前用户身份加密,仅当前登录的系统用户可读取,不会泄露凭证
  • 若需要清除登录状态,直接删除$env:USERPROFILE\.msal_cache\ado_msal_cache.bin文件即可
  • 确保你的Azure AD应用注册中已经开启了「允许公共客户端流」选项,否则交互式登录会被拦截

内容的提问来源于stack exchange,提问作者Arvind Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:15:05