#azure #azure-active-directory
#azure #azure-active-directory
Вопрос:
Я пытаюсь синхронизировать данные между контейнерами Azure в разных учетных записях с помощью мультитетантного приложения и инструмента azcopy.
Синхронизация происходит через «синхронизацию azcopy» и с использованием отдельных токенов SAS как для исходной учетной записи хранения, так и для целевой учетной записи хранения.
Я генерирую токены sas с коротким сроком службы, используя Java SDK, следуя методу ключа делегирования пользователя.
Вот сценарий:
В учетной записи Account1 (назначения) зарегистрировано приложение 1. т.Е. Учетная запись 1 является домашним арендатором для App1. У учетной записи Account1 есть StorageAccount1, а для настроенного контейнера Container1 App1 назначена роль «вкладчика данных большого двоичного объекта хранилища» в StorageAccount1
В учетной записи Account2 (источник) настроены StorageAccount2 и Container2. Для нас это источник данных. Здесь App1 добавляется как ServicePrincipal через:
az ad sp create --id client-id-of-App1-in-Account1
В Account2 для этого SP мы также предоставили роль считывателя данных хранилища Blob как:
az role assignment create
--assignee-object-id <object-id-for-this-sp>
--role 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1
--scope /subscriptions/<subsid-account2>/resourceGroups/<resgrpname>/providers/Microsoft.Storage/storageAccounts/<storagename>
На этом настройка завершена.
Теперь, используя Java SDK, я сгенерировал ключ делегирования пользователя как для источника, так и для назначения. Фрагмент выглядит примерно так, как показано ниже.
genSasToken(String storageAccountName, String containerName,
String tenantId,
String azureAppClientId,
String azureAppClientSecret,
boolean isDestinationAccount) {
BlobContainerSasPermission blobContainerSasPermission =
new BlobContainerSasPermission().setReadPermission(true).setListPermission(true);
if (isDestinationAccount) {
blobContainerSasPermission.setCreatePermission(true)
.setAddPermission(true)
.setWritePermission(true)
.setExecutePermission(true);
}
BlobServiceSasSignatureValues builder =
new BlobServiceSasSignatureValues(OffsetDateTime.now().plusHours(1), blobContainerSasPermission)
.setProtocol(SasProtocol.HTTPS_ONLY);
// Create a BlobServiceClient object which will be used to create a container client
String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net",
storageAccountName);
ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(azureAppClientId)
.clientSecret(azureAppClientSecret)
.tenantId(tenantId)
.build();
BlobServiceClient blobServiceClient =
new BlobServiceClientBuilder().endpoint(endpoint).credential(clientSecretCredential).buildClient();
BlobContainerClient blobContainerClient =
blobServiceClient.getBlobContainerClient(containerName);
// Get a user delegation key for the Blob service that's valid for one hour.
// You can use the key to generate any number of shared access signatures over the lifetime of the key.
OffsetDateTime keyStart = OffsetDateTime.now();
OffsetDateTime keyExpiry = OffsetDateTime.now().plusHours(1);
UserDelegationKey userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart, keyExpiry);
String sas = blobContainerClient.generateUserDelegationSas(builder, userDelegationKey);
return sas;
}
Вышеуказанный метод вызывается как для источника, так и для назначения и выдает нам токены SAS, сгенерированные программно.
Интересная вещь, которая происходит, заключается в следующем:
синхронизация azcopy https://storageaccount2/container2/?sas-token-for2 https://storageaccount1/container1/?sas-token-for1
вышеуказанные ошибки синхронизации отображаются как
INFO: Authentication failed, it is either not correct, or expired, or does not have the correct permission -> github.com/Azure/azure-storage-blob-go/azblob.newStorageError, /Users/runner/go/pkg/mod/github.com/!azure/azure-storage-blob-go@v0.10.1-0.20201022074806-8d8fc11be726/azblob/zc_storage_error.go:42
===== RESPONSE ERROR (ServiceCode=AuthorizationFailure) =====
Description=This request is not authorized to perform this operation.
RequestId:xxx
Time:2021-01-27T10:26:34.9282634Z, Details:
Code: AuthorizationFailure
GET https://storageaccount1.blob.core.windows.net/container1/?comp=propertiesamp;restype=accountamp;se=2021-01-27t11:10:12zamp;sig=-REDACTED-amp;ske=2021-01-27t11:10:12zamp;skoid=xxxamp;sks=bamp;skt=2021-01-27t10:10:12zamp;sktid=xxxamp;skv=2020-02-10amp;sp=racwleamp;spr=httpsamp;sr=camp;sv=2020-02-10amp;timeout=901
User-Agent: [AzCopy/10.8.0 Azure-Storage/0.10 (go1.13; darwin)]
X-Ms-Client-Request-Id: [xxx]
X-Ms-Version: [2019-12-12]
--------------------------------------------------------------------------------
RESPONSE Status: 403 This request is not authorized to perform this operation.
Content-Length: [246]
Content-Type: [application/xml]
Date: [Wed, 27 Jan 2021 10:26:34 GMT]
Server: [Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0]
X-Ms-Client-Request-Id: [xxx]
X-Ms-Error-Code: [AuthorizationFailure]
X-Ms-Request-Id: [xxx]
X-Ms-Version: [2019-12-12]
Но, когда я пытаюсь скопировать из источника на локальный хост, используя тот же токен sas 2, это работает.
синхронизация azcopy https://storageaccount2/container2/sas-token-for2 /tmp
и
когда я пытаюсь скопировать папку localhost в пункт назначения, используя тот же токен sas, он также работает.
синхронизация azcopy / tmp https://storageaccount1/container1/sas-token-for1
Таким образом, токены работают индивидуально, как указано выше.
Но синхронизация azcopy https://storageaccount2/container2/sas-token-for2 https://storageaccount1/container1/sas-token-for1
Сбой.
Любые указания, в чем может быть проблема?
Комментарии:
1.Кроме того, создание sas из azure portal для учетной записи хранилища назначения и ее использование в azcopy работает нормально. т.е. azcopy синхронизирует storageaccount2 / container2 / sas-token-for2 storageaccount1 / container1 / sas-token-generated-from-portal Это работает нормально.
2. Являются ли разрешения, используемые через портал и через код, идентичными для назначения? На самом деле, просто для проверки добавьте все разрешения в целевой SAS, а затем удаляйте по одному за раз. Для синхронизации требуются разрешения на удаление, которые я не вижу в коде, но для управления чем-либо еще мы начинаем с полных разрешений.
3. Да, разрешения в основном идентичны. Через код. Токен назначения sas:
sv=2020-02-10amp;spr=httpsamp;se=2021-01-27T13:00:02Zamp;skoid=REDACTEDamp;sktid=REDACTEDamp;skt=2021-01-27T12:00:02Zamp;ske=2021-01-27T13:00:02Zamp;sks=bamp;skv=2020-02-10amp;sr=camp;sp=racwleamp;sig=REDACTED.
через портал. Целевой токен sas:sv=2019-12-12amp;ss=bamp;srt=coamp;sp=rwlacamp;se=2021-01-27T18:28:32Zamp;st=2021-01-27T10:28:32Zamp;spr=httpsamp;sig=REDACTED.
Ответ №1:
Для синхронизации вам не требуется разрешение на выполнение (которое в любом случае все еще находится в предварительном просмотре). Просто удалите .setExecutePermission(true)
, все должно быть хорошо. Фактически синхронизация должна работать только с разрешениями на чтение, запись и перечисление в пункте назначения.