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

如何用PowerShell的Invoke-RestMethod通过证书获取Microsoft Graph访问令牌

使用PowerShell的Invoke-RestMethod通过证书获取Microsoft Graph访问令牌

核心逻辑说明

通过证书获取Graph访问令牌的核心是生成客户端断言(client_assertion)——这是一个用证书私钥签名的JWT,用来替代客户端密钥完成身份验证。以下是基于Invoke-RestMethod的完整实现:


1. 准备证书

确保你持有对应应用注册的证书(需包含可用私钥),可从本地证书存储获取或导入PFX文件:

# 从当前用户证书存储获取证书(替换为你的证书指纹)
$certThumbprint = "YOUR_CERT_THUMBPRINT"
$cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq $certThumbprint}

# 若证书不在存储中,从PFX文件导入(替换路径和密码)
# $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("path/to/your/cert.pfx", "PFX_PASSWORD")

2. 生成客户端断言(JWT)

客户端断言需要包含指定格式的头部和负载,并用证书私钥签名:

# 定义JWT头部(alg固定为RS256,kid为证书指纹,需去除空格)
$header = @{
    alg = "RS256"
    kid = $cert.Thumbprint.Replace(" ", "")
    typ = "JWT"
} | ConvertTo-Json -Compress

# 定义JWT负载
$tenantId = "YOUR_TENANT_ID"
$clientId = "YOUR_APP_ID"
$tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"

$now = [DateTimeOffset]::UtcNow
$payload = @{
    iss = $clientId
    sub = $clientId
    aud = $tokenEndpoint
    exp = $now.AddSeconds(3600).ToUnixTimeSeconds()  # 令牌1小时后过期
    nbf = $now.ToUnixTimeSeconds()
    jti = [Guid]::NewGuid().ToString()
} | ConvertTo-Json -Compress

# 自定义Base64Url编码函数(符合JWT规范)
function ConvertTo-Base64Url {
    param([string]$input)
    $bytes = [System.Text.Encoding]::UTF8.GetBytes($input)
    $base64 = [System.Convert]::ToBase64String($bytes)
    return $base64.Replace('+', '-').Replace('/', '_').TrimEnd('=')
}

$encodedHeader = ConvertTo-Base64Url $header
$encodedPayload = ConvertTo-Base64Url $payload
$unsignedJwt = "$encodedHeader.$encodedPayload"

# 用证书私钥签名JWT
$privateKey = $cert.PrivateKey
$signatureBytes = $privateKey.SignData([System.Text.Encoding]::UTF8.GetBytes($unsignedJwt), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)
$encodedSignature = ConvertTo-Base64Url ([System.Convert]::ToBase64String($signatureBytes))

# 最终生成客户端断言
$clientAssertion = "$unsignedJwt.$encodedSignature"

3. 调用令牌端点获取访问令牌

通过Invoke-RestMethod发送POST请求获取令牌:

# 构造请求参数
$body = @{
    client_id = $clientId
    scope = "https://graph.microsoft.com/.default"
    grant_type = "client_credentials"
    client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
    client_assertion = $clientAssertion
}

# 发送请求并获取响应
$tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method Post -ContentType "application/x-www-form-urlencoded" -Body $body

# 提取访问令牌
$accessToken = $tokenResponse.access_token
Write-Host "获取到的Microsoft Graph访问令牌:$accessToken"

关键注意事项

  • 应用注册中需已上传该证书的公钥(在「证书和密码」选项卡添加)
  • 应用需配置对应的Microsoft Graph应用权限,且已获得管理员同意
  • 证书必须包含私钥(从PFX导入时需确保密码正确且私钥可访问)

内容的提问来源于stack exchange,提问作者John Ranger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:15:49