如何通过PowerShell获取Azure AD应用的刷新令牌和ID令牌?
Get-AzAccessToken 属于Az模块封装的简化命令,默认仅返回访问令牌,没有内置参数可以直接输出刷新令牌和ID令牌,你可以通过以下两种经过验证的方案获取对应令牌:
方案1:交互式登录场景下通过MSAL公钥客户端直接捕获全量令牌
该方案适用于以用户身份操作Azure资源的场景,不需要手动解析本地缓存,登录完成即可直接拿到三类令牌:
- 前置要求:你注册的Azure AD应用需要提前配置
openid、profile、offline_access以及你需要访问的资源对应的委托权限,若使用Azure PowerShell默认应用ID可跳过权限配置 - 执行以下PowerShell代码,替换对应参数为你自己的应用信息:
Import-Module Az.Accounts # 若要获取自有应用的令牌,将下方clientId替换为你自己的应用(客户端)ID $clientId = "1950a258-227b-4e31-a9cf-717495945fc2" $publicClient = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::Create($clientId) .WithRedirectUri("http://localhost") .Build() # 发起交互式认证请求,必须携带offline_access权限才会返回刷新令牌 $authResult = $publicClient.AcquireTokenInteractive( @("https://management.azure.com/user_impersonation", "openid", "profile", "offline_access") ).ExecuteAsync().GetAwaiter().GetResult() # 直接提取所需令牌 $accessToken = $authResult.AccessToken $idToken = $authResult.IdToken $refreshToken = $authResult.AuthenticationResultParameters.RefreshToken
注意:如果不添加offline_access权限声明,认证返回结果中不会包含刷新令牌;不添加openid、profile权限则不会返回ID令牌
方案2:直接调用Azure AD令牌端点获取令牌
该方案兼容所有OAuth2.0授权流程,不管是交互式用户场景还是服务主体场景都可以使用:
- 若你需要获取刷新令牌和ID令牌,必须使用带用户身份的授权流(授权码流、设备码流、ROPC流等),纯服务主体的客户端凭据流不会返回这两类令牌
- 以设备码流为例,执行以下代码:
# 替换为你的租户ID、应用(客户端)ID $tenantId = "你的Azure AD租户ID" $clientId = "你注册的应用客户端ID" $deviceCodeRequestParams = @{ Method = "Post" Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/devicecode" Body = @{ client_id = $clientId scope = "https://management.azure.com/.default openid profile offline_access" } } $deviceCodeResponse = Invoke-RestMethod @deviceCodeRequestParams Write-Host $deviceCodeResponse.message # 按照提示在浏览器打开地址输入验证码完成认证 # 轮询获取令牌 $tokenRequestParams = @{ Method = "Post" Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" Body = @{ grant_type = "urn:ietf:params:oauth:grant-type:device_code" client_id = $clientId device_code = $deviceCodeResponse.device_code } } $tokenResponse = Invoke-RestMethod @tokenRequestParams # 提取令牌 $accessToken = $tokenResponse.access_token $idToken = $tokenResponse.id_token $refreshToken = $tokenResponse.refresh_token
补充说明:如果你已经通过
Connect-AzAccount完成登录,也可以通过读取Az模块本地的MSAL令牌缓存提取已存储的ID令牌和刷新令牌,但该方法需要操作内部缓存接口,版本兼容性差,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Kattiri Venkataratnam
相关产品推荐
相关产品推荐

