Получите токен обновления Azure Active Directory для ACR

Я пытался использовать поток интерактивной проверки подлинности AAD, чтобы перечислить изображения в данном экземпляре реестра контейнеров Azure (как подробно описано в здесь), который требует как токен доступа AAD, так и токен обновления AAD, чтобы получить обновить / получить доступ к токенам самого ресурса.

Я предположил, что требуемый токен доступа AAD - это простой токен доступа к «management.azure.com», который я получаю с помощью следующего кода:

from azure.identity import DefaultAzureCredential, InteractiveBrowserCredential
credentials = InteractiveBrowserCredential()
aad_access_token = credentials.get_token('https://management.azure.com/.default')

Что возвращает обычный токен доступа (например, eyJ0eX ...). Однако мне не удалось найти никаких ссылок на получение токена обновления программным способом; Похоже, что все пакеты Azure SDK позаботятся об этом в фоновом режиме. Есть ли способ получить этот токен, поскольку поток аутентификации к самому ресурсу (ACR) требует обоих токенов?

Если существует какой-либо другой программный способ перечислить образы контейнеров без токена обновления, я буду более чем счастлив попробовать его.

Также важно отметить, что я работаю в среде, в которой не работает Azure CLI, поэтому я должен использовать пакеты SDK для Python или аналогичные инструменты и не рассчитывать на системные команды, такие как «az login» или «az get credentials».


person FitzChivalry    schedule 24.05.2021    source источник


Ответы (1)


Поэтому у меня возникло несколько недоразумений относительно функциональности обновлений и токенов доступа с ресурсами AAD и Azure. Путем проб и ошибок я обнаружил, что следующий код работает нормально:

import requests
from azure.identity import InteractiveBrowserCredential
from pprint import pprint

CATALOG_SCOPE = "registry:catalog:*"
AZURE_MANAGEMENT_SCOPE_URL = 'https://management.azure.com/.default'
ACR_URL = "YOUR_REPO.azurecr.io"


def get_aad_access_token():
    cred = InteractiveBrowserCredential()
    aad_access_token = cred.get_token(AZURE_MANAGEMENT_SCOPE_URL)
    return aad_access_token.token


def get_acr_refresh_token(acr_url, aad_access_token):
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }

    data = {
        'grant_type': 'access_token',
        'service': acr_url,
        'access_token': aad_access_token
    }

    response = requests.post(f'https://{acr_url}/oauth2/exchange', headers=headers, data=data)
    acr_refresh_token = json.loads(response.content)
    # pprint(response.__dict__)
    return acr_refresh_token['refresh_token']


def get_acr_access_token(acr_refresh_token, acr_url, scope):
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }

    data = {
        'grant_type': 'refresh_token',
        'service': acr_url,
        'scope': scope,
        'refresh_token': acr_refresh_token
    }

    response = requests.post(f'https://{acr_url}/oauth2/token', headers=headers, data=data)
    # pprint(response.__dict__)
    acr_access_token = json.loads(response.content)
    return acr_access_token['access_token']


def list_acr_images(acr_url):
    operation = "/v2/_catalog/"
    aad_access_token = get_aad_access_token()
    acr_refresh_token = get_acr_refresh_token(acr_url, aad_access_token)
    acr_access_token = get_acr_access_token(acr_refresh_token, acr_url, CATALOG_SCOPE)

    headers = {
        'Authorization': f"Bearer {acr_access_token}",
    }

    response = requests.post(f'https://{acr_url}{operation}', headers=headers)
    return json.loads(response.content)


if __name__ == '__main__':
    pprint(list_acr_images(ACR_URL))
person FitzChivalry    schedule 25.05.2021