如何借助Azure AD已加入设备身份通过PowerShell连接函数应用并获取令牌
使用Azure AD已加入设备证书获取Function App访问令牌(PowerShell)
步骤1:定位Azure AD设备证书
Azure AD域加入的设备证书存储在本地机器的Cert:\LocalMachine\My容器中,用于客户端身份验证。运行以下命令筛选目标证书:
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.EnhancedKeyUsageList -match "Client Authentication" -and $_.Subject -match "Azure AD" }
记录输出中的Thumbprint值,后续步骤会用到。
步骤2:定义核心参数
设置Azure AD租户、Function App身份信息及证书指纹:
$tenantId = "你的Azure AD租户ID" # 替换为Function App对应的Azure AD应用客户端ID或应用ID URI $functionAppAudience = "你的Function App客户端ID" $certThumbprint = "步骤1中获取的证书Thumbprint" $tokenEndpoint = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
步骤3:构造签名的JWT断言
使用设备证书生成符合Azure AD要求的JWT断言,用于证明设备身份:
# 加载目标证书 $cert = Get-ChildItem Cert:\LocalMachine\My\$certThumbprint # 构建JWT头部 $header = @{ alg = "RS256" typ = "JWT" x5t = [Convert]::ToBase64String($cert.GetCertHash()) -replace '\+', '-' -replace '/', '_' -replace '=' } | ConvertTo-Json -Compress # 构建JWT主体 $now = [DateTimeOffset]::Now $deviceId = $cert.Subject.Split("=")[1] $body = @{ iss = $deviceId sub = $deviceId aud = $tokenEndpoint exp = $now.AddMinutes(10).ToUnixTimeSeconds() nbf = $now.ToUnixTimeSeconds() iat = $now.ToUnixTimeSeconds() jti = [Guid]::NewGuid().ToString() } | ConvertTo-Json -Compress # 编码头部与主体 $encodedHeader = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($header)) -replace '\+', '-' -replace '/', '_' -replace '=' $encodedBody = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($body)) -replace '\+', '-' -replace '/', '_' -replace '=' $unsignedJwt = "$encodedHeader.$encodedBody" # 用证书私钥签名JWT $signature = $cert.PrivateKey.SignData( [System.Text.Encoding]::UTF8.GetBytes($unsignedJwt), [Security.Cryptography.HashAlgorithmName]::SHA256, [Security.Cryptography.RSASignaturePadding]::Pkcs1 ) $encodedSignature = [Convert]::ToBase64String($signature) -replace '\+', '-' -replace '/', '_' -replace '=' $signedJwt = "$unsignedJwt.$encodedSignature"
步骤4:请求Function App访问令牌
调用Azure AD令牌端点,提交签名后的断言获取令牌:
$requestBody = @{ client_id = $deviceId client_assertion = $signedJwt client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" grant_type = "client_credentials" scope = "$functionAppAudience/.default" } $tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method Post -Body $requestBody -ContentType "application/x-www-form-urlencoded" # 提取并输出访问令牌 $accessToken = $tokenResponse.access_token Write-Host "Function App访问令牌:`n$accessToken"
关键注意事项
- 系统上下文运行的PowerShell默认具备访问本地机器证书存储的权限,无需额外授权。
- 需在Azure AD中为设备服务主体分配Function App的访问权限(如添加角色或应用权限)。
- 若使用Function App的应用ID URI作为受众,将
scope参数替换为"https://<你的Function App域名>/.default"。
内容的提问来源于stack exchange,提问作者Christian Pedersen
相关产品推荐
相关产品推荐

