当前位置: 首页 > 知识库问答 >
问题:

从Azure批处理访问Azure密钥库

潘嘉颖
2023-03-14

我正在尝试从运行在我的Azure批处理节点池中的VM访问我的Azure密钥库中的机密。

然而,我总是遇到例外:

异常消息:已尝试%1个证书。无法获取访问令牌。

具有指纹的证书#1的异常my-thumbprint:密钥集不存在

到目前为止,我一直遵循以下说明:https://docs.microsoft.com/en-us/Azure/key-vault/service-to-service-authentication

本文概述了Azure批处理的场景,并指出我应该使用一个服务主体。我希望确保版本控制中没有秘密或密钥,因此我使用本地密钥库中的证书的第一种方法来登录Azure AD。

在本地作为可执行文件运行下面的所有内容可以正常工作,但在Azure批处理池节点上运行时会失败。

到目前为止,我要做的步骤是:

为创建的服务主体创建密钥库访问策略(在azure portal UI中完成)。

以PFX/PEM格式下载创建的证书(在Azure Portal UI中完成)。

确保证书上有PFX密码(我之所以这样做是因为在步骤6中将证书上载到azure批处理中需要关联的密码):https://coombes.nz/blog/azure-keyvault-export-certificate/

# Replace these variables with your own values
$vaultName = "YOUR-KEYVAULT-NAME"
$certificateName = "YOUR-CERTIFICATE-NAME"
$pfxPath = [Environment]::GetFolderPath("Desktop") + "\$certificateName.pfx"
$password = "YOUR-CERTIFICATE-PASSWORD"

$pfxSecret = Get-AzureKeyVaultSecret -VaultName $vaultName -Name $certificateName
$pfxUnprotectedBytes = [Convert]::FromBase64String($pfxSecret.SecretValueText)
$pfx = New-Object Security.Cryptography.X509Certificates.X509Certificate2
$pfx.Import($pfxUnprotectedBytes, $null, [Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$pfxProtectedBytes = $pfx.Export([Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $password)
[IO.File]::WriteAllBytes($pfxPath, $pfxProtectedBytes)

将证书本地安装到我的计算机的LocalMachine存储中(用于本地测试)。

将证书上载到Azure批处理中(使用Azure Portal UI上载)。

将证书与适当的节点池关联并重新引导节点(目前使用Azure Portal UI)。

我在Azure批处理上运行的应用程序包是一个简单的控制台可执行文件。将AzuReserviceAuthConnectionString设置为Runas=App;AppId={AppId};TenantId={TenantId};CertificateThumbprint={Thumbprint};CertificateStoreLocation={LocalMachine}并且要检索机密的其余密钥库代码如下所示:

Environment.SetEnvironmentVariable("AzureServicesAuthConnectionString", "RunAs=App;AppId=<MY-APP-ID>;TenantId=<MY-TENANT>;CertificateThumbprint=<MY-THUMBPRINT>;CertificateStoreLocation=LocalMachine");

AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(Environment.GetEnvironmentVariable("AzureServicesAuthConnectionString"));
KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
var secret = await keyVaultClient.GetSecretAsync("<MY-SECRET>").ConfigureAwait(false);
var message = secret.Value;
Console.WriteLine(message);

在本地运行良好,但在远程节点上失败。我能够RDP到Azure批处理节点中,并看到已为本地计算机安装了证书。

我想知道如何解决我的错误,或者我的上述步骤是否在某种程度上是错误的?

共有1个答案

颛孙俊
2023-03-14

除了上述内容,我还遵循了Sam Cogan文章中的说明:https://samcogan.com/secure-credential-access-with-azure-batch-and-keyvault/

不过,我收到的问题与原来的问题相同。我对Sam Cogan文章的错误和相关的再现步骤是:

Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: RunAs=App;AppId=<My Service Principal ID>;TenantId=<My Tenant ID>;CertificateThumbprint=<My cert thumbprint>;CertificateStoreLocation=LocalMachine, Resource: https://vault.azure.net, Authority: https://login.windows.net/<My Tenant ID>. Exception Message: Tried 1 certificate(s). Access token could not be acquired.
Exception for cert #1 with thumbprint <My cert thumbprint>: Keyset does not exist

我的再现步骤是:

    null
C:\Program Files (x86)\Windows Kits\10\bin\x64> .\makecert.exe -sv batchcertificate6.pvk -n "cn=andybatch6.cert.mydomain.org" batchcertificate6.cer -r -pe -a sha256 -len 2048
C:\Program Files (x86)\Windows Kits\10\bin\x64> .\pvk2pfx.exe -pvk batchcertificate6.pvk -spc batchcertificate6.cer -pfx batchcertificate7.pfx -po <MyPassword>  -pi <MyPassword>  
#Point the script at the cer file you created 

$cerCertificateFilePath = 'C:\Program Files (x86)\Windows Kits\10\bin\x64\batchcertificate6.cer' 
$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 
$cer.Import($cerCertificateFilePath)

#Load the certificate into memory 
$credValue = [System.Convert]::ToBase64String($cer.GetRawCertData()) 

#Create a new AAD application that uses this certifcate 
$newADApplication = New-AzureRmADApplication -DisplayName "<My display name>" -HomePage "<my url>" -IdentifierUris " <my url>" -certValue $credValue 

#Create new AAD service principle that uses this application 
$newAzureAdPrincipal = New-AzureRmADServicePrincipal -ApplicationId $newADApplication.ApplicationId
Set-AzureRmKeyVaultAccessPolicy -VaultName 'myvaultname' -ServicePrincipalName '<my url>' -PermissionsToSecrets 'Get'
Environment.SetEnvironmentVariable("AzureServicesAuthConnectionString",
                    "RunAs=App;" +
                    "AppId=<the app id of my active directory app registration> ;" +
                    "TenantId=<my subscription tenant id>;" +
                    "CertificateThumbprint=<the thumbprint of my cert>;" +
                    "CertificateStoreLocation=LocalMachine");

                AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider(Environment.GetEnvironmentVariable("AzureServicesAuthConnectionString"));
                KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
                var secret = await keyVaultClient.GetSecretAsync("https://<my vault name>.vault.azure.net/secrets/<secret name>/<secret id>")
                        .ConfigureAwait(false);
                message = secret.Value;
                Console.WriteLine(message);

我的代码使用上面的连接字符串在本地与安装的证书一起工作,但是在Azure批处理上运行时出现了上面提到的异常。

 类似资料:
  • 是否有一种方法可以使用Delphi访问Azure密钥库?我可以使用柏林的data.cloud.azureapi单元访问数据库和blob存储,但想从密钥库中获取数据库连接字符串,但似乎找不到任何用于此操作的代码。

  • 我已经在Azure广告中注册了我的应用程序,并获得了应用程序ID和身份验证密钥,我允许我的应用程序从密钥库中读取机密。在我的U-SQL脚本中,我引用了所有需要的程序集。 当我在本地运行我的脚本时,一切都很好(这意味着从本地机器到AD和密钥库的连接是正常的),但是当我在远程数据湖分析帐户上提交它以执行时,我得到了以下错误: 无法解析远程名称:'my-key-vault-name.vault.azur

  • 我正在python中构建由事件网格事件触发的Azure函数,它应该能够从Kay Vault收集秘密。 我将系统分配的托管标识添加到我的功能应用程序中,然后我可以在密钥库访问策略中选择我的应用程序。我授予它如下所示的权限: (我尝试了不同的组合在这一个)

  • 我无法访问托管密钥库中的存储帐户密钥。下面是我的代码: 似乎$secret.secretValueText为空/null。如何正确检索存储帐户密钥?这就是出现的错误。

  • 我得到的错误是“Access Denied”,这(我认为)意味着id、secret和Vault的url没有问题。但是,我不知道我可以做什么来修复这个错误,也许在Azure门户中有一个设置阻止我读取一个秘密?