Поделиться через


Проверка подлинности приложений Go в службах Azure во время локальной разработки с помощью субъектов-служб

При создании облачных приложений разработчикам необходимо выполнять отладку и тестирование приложений на локальной рабочей станции. Когда приложение выполняется на рабочей станции разработчика во время локальной разработки, оно по-прежнему должно пройти проверку подлинности в любых службах Azure, используемых приложением. В этой статье описывается настройка выделенных главных элементов приложения для использования во время локальной разработки.

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

Выделенные служебные учетные записи для локальной разработки позволяют следовать принципу наименьших привилегий при разработке приложений. Так как разрешения ограничены именно тем, что необходимо для приложения во время разработки, код приложения не может случайно получить доступ к ресурсу Azure, предназначенному для использования другим приложением. Это также препятствует возникновению ошибок при перемещении приложения в рабочую среду, так как приложение было перегружено в среде разработки.

Субъект-служба приложений настраивается для приложения при регистрации приложения в Azure. При регистрации приложений для локальной разработки рекомендуется:

  • Создайте отдельные регистрации приложений для каждого разработчика, работающего над приложением. Это позволит создать отдельные субъекты-службы приложений для каждого разработчика, которые будут использоваться во время локальной разработки и избежать необходимости совместного использования учетных данных для одного субъекта-службы приложений.
  • Создание отдельных регистраций приложений для каждого приложения. Это ограничивает разрешения приложения только тем, что требуется приложению.

Во время локальной разработки переменные среды задаются с удостоверением служебного принципала приложения. Пакет SDK Azure для Go считывает эти переменные среды и использует эти сведения для проверки подлинности приложения в необходимых ресурсах Azure.

1. Регистрация приложения в Azure

Объекты служебного принципала приложения создаются с регистрацией приложения в Azure. Это можно сделать с помощью портала Azure или Azure CLI.

Команды Azure CLI можно выполнять в Azure Cloud Shell или на рабочей станции с установленнымAzure CLI.

Сначала используйте команду az ad sp create-for-rbac, чтобы создать новую учетную запись в службе для приложения. Команда также создает регистрацию приложения для приложения одновременно.

az ad sp create-for-rbac --name <service-principal-name>

Выходные данные этой команды будут выглядеть следующим образом. Запишите эти значения или оставьте это окно открытым, так как вам потребуется эти значения в следующих шагах и не сможете снова просмотреть значение пароля (секрет клиента). Однако при необходимости можно добавить новый пароль, не делая недействительными субъект-службы или существующие пароли.

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "<service-principal-name>",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

2. Создание группы безопасности Microsoft Entra для локальной разработки

Так как обычно существует несколько разработчиков, работающих над приложением, рекомендуется создать группу безопасности Microsoft Entra, чтобы инкапсулировать роли (разрешения), необходимые приложению в локальной разработке, а не назначать роли отдельным объектам субъекта-службы. Это дает следующие преимущества:

  • Каждому разработчику гарантируется назначение одних и тех же ролей, поскольку они назначаются на уровне группы.
  • Если для приложения требуется новая роль, ее нужно просто добавить в группу Microsoft Entra для этого приложения.
  • Если новый разработчик присоединяется к команде, для него создается новый принципал приложения и добавляется в группу, обеспечивая разработчику правильные разрешения для работы с приложением.

Команда az ad group create используется для создания групп безопасности в Microsoft Entra ID. Требуются параметры --display-name и --main-nickname. Имя, заданное группе, должно быть основано на имени приложения. Также полезно включить фразу, например local-dev, в имя группы, чтобы указать назначение группы.

az ad group create \
    --display-name MyDisplay \
    --mail-nickname MyDisplay  \
    --description "<group-description>"

Скопируйте значение свойства id в выходных данных команды. Это идентификатор объекта для группы. Вам потребуется это в последующих шагах. Вы также можете использовать команду az ad group show для получения этого свойства.

Чтобы добавить участников в группу, требуется идентификатор объекта субъекта-службы приложения, который отличается от идентификатора приложения. Используйте az ad sp list для перечисления доступных субъектов-служб. Команда параметра --filter принимает фильтры стилей OData и может использоваться для фильтрации списка, как показано ниже. Параметр --query ограничивает столбцы только интересующими.

az ad sp list \
    --filter "startswith(displayName, 'msdocs')" \
    --query "[].{objectId:id, displayName:displayName}" \
    --output table

Затем команду az ad group member add можно использовать для добавления участников в группы.

az ad group member add \
    --group <group-name> \
    --member-id <object-id>

Заметка

По умолчанию создание групп безопасности Microsoft Entra ограничено определенными привилегированными ролями в каталоге. Если вы не можете создать группу, обратитесь к администратору каталога. Если вы не можете добавить участников в существующую группу, обратитесь к владельцу группы или администратору каталога. Дополнительные сведения см. в статье Управление группами Microsoft Entra и членством в группах.

3. Назначение ролей приложению

Затем необходимо определить, какие роли (разрешения) приложения требуются для ресурсов и назначить эти роли приложению. В этом примере роли назначаются группе Microsoft Entra, созданной на шаге 2. Роли можно назначать в ресурсе, группе ресурсов или области подписки. В этом примере показано, как назначать роли в пределах группы ресурсов, поскольку большинство приложений группируют все ресурсы Azure в один набор ресурсов.

Пользователю, группе или сервисному принципалу приложения назначена роль в Azure с помощью команды az role assignment create. Группу можно указать с идентификатором объекта. Субъект-службу приложения можно указать с помощью идентификатора приложения.

az role assignment create --assignee <appId or objectId> \
    --scope /subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName> \
    --role "<roleName>" 

Чтобы получить имена ролей, которые можно назначить, используйте команду az role definition list.

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

Например, чтобы разрешить субъекту-службе приложения с помощью appId чтения, записи и удаления доступа к контейнерам BLOB-объектов службы хранилища Azure и данным во всех учетных записях хранения в msdocs-go-sdk-example группы ресурсов в подписке с идентификатором , вы назначите субъекту-службе приложений роль участника хранилища BLOB-объектов с помощью следующей команды.

az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
    --scope /subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-go-sdk-auth-example \
    --role "Storage Blob Data Contributor"

Сведения о назначении разрешений на уровне ресурса или подписки с помощью Azure CLI см. в статье Назначение ролей Azure с помощьюAzure CLI.

4. Задание переменных среды локального окружения разработки

Объект DefaultAzureCredential будет искать сведения субъекта-службы в наборе переменных среды во время выполнения. Так как большинство разработчиков работают над несколькими приложениями, рекомендуется использовать пакет, например godotenv для доступа к среде из файла .env, хранящегося в каталоге приложения во время разработки. Это определяет переменные среды, используемые для проверки подлинности приложения в Azure, таким образом, что они могут использоваться только этим приложением.

Файл .env никогда не проверяется в системе управления версиями, так как он содержит секретный ключ приложения для Azure. Стандартный файл .gitignore для Go автоматически исключает файл .env из регистрации.

Чтобы использовать пакет godotenv, сначала установите пакет в приложении.

go get github.com/joho/godotenv

Затем создайте файл .env в корневом каталоге приложения. Задайте значения переменной среды со значениями, полученными из процесса регистрации приложения следующим образом:

  • AZURE_CLIENT_ID → значение идентификатора приложения.
  • AZURE_TENANT_ID → Значение идентификатора клиента.
  • AZURE_CLIENT_SECRET → пароль или учетные данные, созданные для приложения.
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6

Наконец, в коде запуска приложения используйте библиотеку godotenv для чтения переменных среды из файла .env при запуске.

// Imports of fmt, log, and os omitted for brevity 
import "github.com/joho/godotenv"

environment := os.Getenv("ENVIRONMENT")

if environment == "development" {
    fmt.Println("Loading environment variables from .env file")
    
    // Load the .env file
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatalf("Error loading .env file: %v", err)
    }
}

5. Реализация DefaultAzureCredential в приложении

Для проверки подлинности клиентских объектов Пакета SDK Azure в Azure приложение должно использовать класс DefaultAzureCredential из пакета azidentity. В этом сценарии DefaultAzureCredential обнаружит, что переменные среды AZURE_CLIENT_ID, AZURE_TENANT_IDи AZURE_CLIENT_SECRET заданы, и считает эти переменные, чтобы получить учетные данные для подключения к Azure.

Сначала добавьте пакет azidentity в приложение.

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

Затем для любого кода Go, создающего клиентский объект Azure SDK в приложении, необходимо выполнить следующие действия.

  1. Импортируйте пакет azidentity.
  2. Создайте экземпляр типа DefaultAzureCredential.
  3. Передайте экземпляр типа DefaultAzureCredential конструктору клиента Azure SDK.

Пример этого показан в следующем сегменте кода.

import (
	"context"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

const (
	account       = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

func main() {
    // create a credential
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
      // TODO: handle error
    }
    
    // create a client for the specified storage account
    client, err := azblob.NewClient(account, cred, nil)
    if err != nil {
      // TODO: handle error
    }
    
    // TODO: perform some action with the azblob Client
    // _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}