Доступ к хранилищу ключей Azure из пакета Azure - PullRequest
1 голос
/ 25 сентября 2019

Я пытаюсь получить доступ к секретам в своем хранилище ключей Azure из виртуальных машин, работающих в моем пуле узлов Azure.

Однако я продолжаю сталкиваться с исключением:

Сообщение об исключении: Пробовал 1 сертификат (ы).Не удалось получить токен доступа.

Исключение для сертификата № 1 с отпечатком большого пальца. MY-THUMBPRINT: Набор ключей не существует

До сих пор я следил заинструкции, изложенные здесь: https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication

В статье описывается сценарий пакетной службы Azure и указывается, что мне следует использовать принципала службы.Я хочу убедиться, что в управлении версиями нет секретов или ключей, поэтому я использую первый метод сертификата в локальном хранилище ключей для входа в Azure AD.

Локальный запуск всего нижеприведенного как исполняемый файлнормально, но завершается неудачно при запуске на узле пакетного пула Azure.

На этом шаге я пока проделал следующие шаги:

  1. Создание участника службы и связанного сертификата в keyvault: az ad sp create-for-rbac --name myserviceprincipal --create-cert --cert mycertname --keyvault mykeyvaultname.Сохраните идентификатор приложения участника службы и идентификатор клиента для использования в AzureServicesAuthConnectionString.

  2. Создание политики доступа к хранилищу ключей для созданного участника службы (выполняется в пользовательском интерфейсе портала Azure).

  3. Загрузите созданный сертификат в формате PFX / PEM (выполняется в пользовательском интерфейсе портала Azure).

  4. Обеспечение пароля PFX в сертификате (я делаю этопоскольку загрузка сертификата в пакет Azure на шаге 6 требует соответствующего пароля): 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).

Связывание сертификата с соответствующим пулом узлов и перезагрузка узлов (на данный момент используется пользовательский интерфейс портала Azure).

Мой пакет приложений, работающий в AzureBatch - это простой консольный исполняемый файл.Для AzureServicesAuthConnectionString установлено значение 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 и увидеть, что сертификат установлен для локального компьютера.

Мне интересно, как устранить мою ошибку или мои действия, описанные выше, каким-то образом неверны?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Чтобы получить доступ к сертификату, он должен быть связан и установлен для «текущего пользователя».Возможно, у LocalMachine нет соответствующего уровня разрешений?

В пакете Azure убедитесь, что загруженный сертификат связан с:

Имя хранилища: «Мое» Расположение хранилища: «CurrentUser»'

Этот пост был полезен: https://github.com/nabhishek/customactivity_sample/tree/linkedservice

Как и этот пост: X509Certificate - Набор ключей не существует

Строка подключения в C #exe выглядит так:

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=CurrentUser");

                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);
0 голосов
/ 29 сентября 2019

В дополнение к вышесказанному, я следовал инструкциям из статьи Сэма Когана: https://samcogan.com/secure-credential-access-with-azure-batch-and-keyvault/

Однако я получаю ту же проблему, что и оригинальный вопрос.Моя ошибка и связанные шаги репро для статьи Сэма Когана:

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

Мои шаги репро:

  1. Создание сертификата (я добавил -a sha256 -len 2048 частькак я описал и исправил здесь ту же ошибку: Как пройти проверку подлинности с помощью Key Vault из пакета Azure )
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
Преобразовать сертификат на шаге 1 в формат PFX:
C:\Program Files (x86)\Windows Kits\10\bin\x64> .\pvk2pfx.exe -pvk batchcertificate6.pvk -spc batchcertificate6.cer -pfx batchcertificate7.pfx -po <MyPassword>  -pi <MyPassword>  
Создайте приложение ActiveDirectory и принципал службы, свяжите и загрузите созданный сертификат:
#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'
Загрузите сертификат (pfx) в пакет Azure через портал.Свяжите его с моим пулом узлов как LocalMachine и перезагрузите узлы.Запустите приложение со строкой подключения, например:
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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...