Подключение к REST API хранилища BLOB-объектов Azure с помощью axios, Node.js

Я пытаюсь подключиться к API хранилища BLOB-объектов Azure с помощью Node.js. Я специально не хочу использовать SDK хранилища BLOB-объектов, я хочу использовать axios для доступа к REST API. Я просто пытаюсь выполнить простой вызов контейнеров со списком, как указано здесь: https://docs.microsoft.com/en-us/rest/api/storageservices/list-containers2. Однако у меня возникают проблемы с авторизацией.

Вот мой простой призыв к аксиомам:

try {
  const azureRes = await axios({
    method: 'GET',
    url:
      'https://<accountname>.blob.core.windows.net/?comp=list',
    headers: {
      'x-ms-version': '2017-11-09',
      Authorization:
        'Bearer <access_token>'
    }
  });
  console.log('azureRes', azureRes);
} catch (err) {
  console.log('err:', err);
}

Однако я получаю ответ с кодом состояния 403 и сообщением об ошибке:

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

Я прохожу аутентификацию в соответствии с https://docs.microsoft.com/en-us/rest/api/storageservices/authorize-with-azure-active-directory, и я получаю свой токен доступа на вкладке Ключи доступа учетной записи хранения Azure. Почему моя аутентификация не работает?


person rbuzby    schedule 24.11.2020    source источник
comment
Не могли бы вы подробнее рассказать, как получить токен доступа?   -  person Jim Xu    schedule 25.11.2020
comment
На вкладке "Ключи доступа" учетной записи хранения Azure в разделе "Ключ".   -  person rbuzby    schedule 25.11.2020
comment
Привет. Это ключ доступа, а не токен доступа к AD. Если вы хотите получить доступ к хранилищу через авторизацию AD, обратитесь к моему решению.   -  person Jim Xu    schedule 26.11.2020


Ответы (1)


Если вы хотите получить доступ к REST API больших двоичных объектов Azure с аутентификацией Azure AD, выполните следующие действия.

  1. Назначьте Storage Blob Data Contributor пользователю или субъекту службы AD. Дополнительные сведения см. В здесь и здесь
az role assignment create \
    --role "Storage Blob Data Contributor" \
    --assignee " supported format: object id, user sign-in name, or service principal name." \
    --scope "/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"
  1. Получите токен Azure AD

Если вы используете субъект-службу, мы можем получить токен доступа с помощью следующего API. Но обратите внимание, что если вы вызовете остальной API в приложении реакции, вы получите ошибку cors, и мы не сможем включить cors в Azure AD. Поэтому я предлагаю вам вызвать остальной API в серверном приложении

POST /{tenant}/oauth2/v2.0/token HTTP/1.1          
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=
&scope=http//storage.azure.com/.default
&client_secret=
&grant_type=client_credentials

Если вы используете пользователя Azure AD, вы можете интегрировать аутентификацию Azure AD в свое приложение реакции с пакетом react-aad-msal. Информацию о том, как его настроить, см. В образце

  1. Вызов API
try {
  const azureRes = await axios({
    method: 'GET',
    url:
      'https://<accountname>.blob.core.windows.net/?comp=list',
    headers: {
      'x-ms-version': '2017-11-09',
      Authorization:
        'Bearer <access_token>'
    }
  });
  console.log('azureRes', azureRes);
} catch (err) {
  console.log('err:', err);
}

Обновление. Чтобы узнать, как создать токен sas, см. следующий код.

  1. установить pcakge crypto-js
npm install crypto-js

  1. код
import * as CryptoJS from 'crypto-js';
const accountName =<>;
  const key=<>;
  const start = new Date(new Date().getTime() - (15 * 60 * 1000));
  const end = new Date(new Date().getTime() + (30 * 60 * 1000));
const signedpermissions = 'rwdlac';
  const signedservice = 'b';
  const signedresourcetype = 'sco';
  const signedexpiry = end.toISOString().substring(0, end.toISOString().lastIndexOf('.')) + 'Z';
  const signedProtocol = 'https';
  const signedversion = '2018-03-28';

  const StringToSign =
      accountName+ '\n' +
      signedpermissions + '\n' +
      signedservice + '\n' +
      signedresourcetype + '\n' +
       '\n' +
      signedexpiry + '\n' +
       '\n' +
      signedProtocol + '\n' +
signedversion + '\n';

 var str =CryptoJS.HmacSHA256(StringToSign,CryptoJS.enc.Base64.parse(key));
 var sig = CryptoJS.enc.Base64.stringify(str);
 
 
  const sasToken =`sv=${(signedversion)}&ss=${(signedservice)}&srt=${(signedresourcetype)}&sp=${(signedpermissions)}&se=${encodeURIComponent(signedexpiry)}&spr=${(signedProtocol)}&sig=${encodeURIComponent(sig)}`;

const blobUrl= `<you blob URL>?{sasToken }`
person Jim Xu    schedule 26.11.2020
comment
С Javascript SDK мне нужно только предоставить строку подключения, связанную с моей учетной записью хранения, для аутентификации. Должен быть более простой способ аутентификации с помощью REST API. - person rbuzby; 27.11.2020
comment
@rbuzby В настоящий момент мы можем использовать подпись общего доступа с общим ключом или токен Azure Active Directory для доступа к API отдыха Azure Blob и не можем использовать ключ доступа для этого напрямую: docs.microsoft.com/en-us/rest/api/storageservices/. Кроме того, в соответствии с вашими потребностями, я думаю, вы можете использовать подпись общего доступа для ее реализации: docs.microsoft.com/en-us/azure/storage/blobs/ - person Jim Xu; 30.11.2020
comment
@rbuzby Информацию о том, как создать sas, см. в документации. .microsoft.com / en-us / rest / api / storageservices /. - person Jim Xu; 30.11.2020