Azure 自动化帐户和 Key Vault 证书检索问题

问题描述 投票:0回答:1

我在尝试从 Azure Automation Runbook 中的 Azure Key Vault 检索证书时遇到问题。尽管验证了证书是否存在,但我在运行脚本时遇到了错误。自动化帐户已分配 Key Vault 证书用户和 Key Vault 机密用户角色,并且我已确保 API 权限正确 (Microsoft Graph Sites.FullControl.All、Microsoft Graph User.Read、SharePoint Sites.FullControl.All )。我还检查了 Entra ID,并确认启用了基于证书的身份验证。

错误输出:

Completed


Environments                                                                                           Context
------------                                                                                           -------
{[AzureChinaCloud, AzureChinaCloud], [AzureCloud, AzureCloud], [AzureUSGovernment, AzureUSGovernment]} Microsoft.Azure.…
Exception calling ".ctor" with "3" argument(s): "Array may not be empty or null. (Parameter 'rawData')"
System.Management.Automation.ParameterBindingValidationException: Cannot bind argument to parameter 'ClientCertificate' because it is null.
   at System.Management.Automation.ParameterBinderBase.ValidateNullOrEmptyArgument(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, Type argumentType, Object parameterValue, Boolean recurseIntoCollections)
   at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
   at System.Management.Automation.CmdletParameterBinderController.BindNamedParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter)
   at System.Management.Automation.ParameterBinderController.BindNamedParameters(UInt32 parameterSets, Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
   at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
   at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
   at System.Management.Automation.CommandProcessor.Prepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
   at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
--- End of stack trace from previous location ---
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
   at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

我并不完全有信心以最好的方式完成这件事,因为我依赖 ChatGPT 的指导。

PS脚本:

# Login with Managed Identity (for Azure Automation Account)
Write-Host "Logging in with Automation Account Managed Identity..."
Connect-AzAccount -Identity
Write-Host "Logged in with Managed Identity."

# Set API Key
$APIKey = Get-AutomationVariable -Name '...'
Write-Host "API Key retrieved: $APIKey"

# Set SharePoint Site URL and Folder
$SharePointSiteUrl = "..."
$SharePointFolder = "..."

# Set Azure App Registration credentials
$tenantId = "..."
$clientId = "..."

# Retrieve the certificate from Azure Key Vault
Write-Host "Retrieving certificate from Azure Key Vault..."
$certificate = Get-AzKeyVaultCertificate -VaultName '...' -Name '...'

# Check if certificate retrieval was successful
if ($certificate -eq $null) {
    Write-Host "Error: Certificate not found in Key Vault!"
    exit
}

# Convert from Base64 to Byte Array and create the certificate object
$pfxBytes = [Convert]::FromBase64String($certificate.SecretValueText)
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($pfxBytes, $null, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
Write-Host "Certificate retrieved successfully."

# Use the certificate to authenticate with Azure AD and get an access token
Write-Host "Authenticating with Azure AD using the certificate..."
$GraphConnection = Get-MsalToken -ClientCertificate $cert -ClientId $clientId -TenantId $tenantId

# Get the access token from the authentication response
$Token = $GraphConnection.AccessToken

# Check if the token was retrieved
if (-not $Token) {
    Write-Host "Error: Failed to retrieve access token!"
    exit
}

Write-Host "Access token retrieved successfully."

所有占位符均已替换为脚本中的实际详细信息,而不是保留为“...”

azure powershell azure-active-directory
1个回答
0
投票

要从 Azure Key Vault 检索证书并生成访问令牌,请使用

Get-AzKeyVaultSecret
命令而不是
Get-AzKeyVaultCertificate
命令。

# Parameters
$tenantID = 'TenantID'  
$clientID = 'ClientID'   
$keyVaultName = 'autokvruk'  
$certName = 'rukcerttdyypfx'  
$scope = 'https://graph.microsoft.com/.default' 

Connect-AzAccount -Identity

# Retrieve the certificate from Azure Key Vault as a Base64-encoded string
$pfxSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $certName -AsPlainText

# Convert the Base64-encoded string to bytes
$secretByte = [Convert]::FromBase64String($pfxSecret)

# Load the certificate using the X509Certificate2 class
$x509Cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2($secretByte, $null, [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)

# Get the MSAL token using the certificate
try {
    $token = Get-MsalToken -ClientId $clientID -TenantId $tenantID -ClientCertificate $x509Cert -Scope $scope
    Write-Host "Successfully retrieved the token."
    Write-Host "Access Token: $($token.AccessToken)"
} catch {
    Write-Host "Error getting the token: $_"
}

访问令牌生成成功:

enter image description here

已在 Azure Key Vault 中上传

.pfx
证书:

enter image description here

并将

.cer
证书上传到Microsoft Entra ID应用程序:

enter image description here

  • 将 Key Vault 证书用户和 Key Vault 机密用户角色分配给托管身份。
  • 在PowerShell 7.1版本中执行脚本。

参考:

powershell - 从 Azure Key Vault 检索 PFX 证书 - 堆栈内存溢出

© www.soinside.com 2019 - 2024. All rights reserved.