Создание ресурса Иммерсивное средство чтения и настройка проверки подлинности Microsoft Entra

В этой статье объясняется, как создать ресурс Иммерсивное средство чтения с помощью предоставленного скрипта. Этот скрипт также настраивает проверку подлинности Microsoft Entra. Каждый раз при создании ресурса Иммерсивное средство чтения, будь то с помощью этого скрипта или на портале, он должен быть настроен с разрешениями Microsoft Entra.

Скрипт создает и настраивает все необходимые Иммерсивное средство чтения и ресурсы Microsoft Entra для вас. Однако можно также настроить проверку подлинности Microsoft Entra для существующего ресурса Иммерсивное средство чтения, если вы уже создали его в портал Azure. Скрипт сначала ищет существующие ресурсы Иммерсивное средство чтения и Microsoft Entra в подписке и создает их только в том случае, если они еще не существуют.

Для некоторых клиентов может потребоваться создать несколько Иммерсивное средство чтения ресурсов, для разработки и рабочей среды или, возможно, для разных регионов, где развернута служба. В этих случаях можно вернуться и использовать скрипт несколько раз, чтобы создать разные Иммерсивное средство чтения ресурсы и настроить их с разрешениями Microsoft Entra.

Разрешения

Указанный владелец подписки Azure имеет все необходимые разрешения для создания ресурса Иммерсивное средство чтения и настройки проверки подлинности Microsoft Entra.

Если вы не являетесь владельцем, требуются следующие область разрешения.

  • Участник. Необходимо иметь по крайней мере роль участника, связанную с подпиской Azure:

    Screenshot of contributor built-in role description.

  • Разработчик приложений. Необходимо иметь по крайней мере роль разработчика приложений, связанную с идентификатором Microsoft Entra ID:

    Screenshot of the developer built-in role description.

Дополнительные сведения см. в статье Встроенные роли Microsoft Entra.

Настройка ресурсов PowerShell

  1. Для начала откройте Azure Cloud Shell. Убедитесь, что Cloud Shell имеет значение PowerShell в раскрывающемся списке в верхнем левом углу или введите pwsh.

  2. Скопируйте следующий фрагмент кода и вставьте его в оболочку.

    function Create-ImmersiveReaderResource(
        [Parameter(Mandatory=$true, Position=0)] [String] $SubscriptionName,
        [Parameter(Mandatory=$true)] [String] $ResourceName,
        [Parameter(Mandatory=$true)] [String] $ResourceSubdomain,
        [Parameter(Mandatory=$true)] [String] $ResourceSKU,
        [Parameter(Mandatory=$true)] [String] $ResourceLocation,
        [Parameter(Mandatory=$true)] [String] $ResourceGroupName,
        [Parameter(Mandatory=$true)] [String] $ResourceGroupLocation,
        [Parameter(Mandatory=$true)] [String] $AADAppDisplayName,
        [Parameter(Mandatory=$true)] [String] $AADAppIdentifierUri,
        [Parameter(Mandatory=$true)] [String] $AADAppClientSecretExpiration
    )
    {
        $unused = ''
        if (-not [System.Uri]::TryCreate($AADAppIdentifierUri, [System.UriKind]::Absolute, [ref] $unused)) {
            throw "Error: AADAppIdentifierUri must be a valid URI"
        }
    
        Write-Host "Setting the active subscription to '$SubscriptionName'"
        $subscriptionExists = Get-AzSubscription -SubscriptionName $SubscriptionName
        if (-not $subscriptionExists) {
            throw "Error: Subscription does not exist"
        }
        az account set --subscription $SubscriptionName
    
        $resourceGroupExists = az group exists --name $ResourceGroupName
        if ($resourceGroupExists -eq "false") {
            Write-Host "Resource group does not exist. Creating resource group"
            $groupResult = az group create --name $ResourceGroupName --location $ResourceGroupLocation
            if (-not $groupResult) {
                throw "Error: Failed to create resource group"
            }
            Write-Host "Resource group created successfully"
        }
    
        # Create an Immersive Reader resource if it doesn't already exist
        $resourceId = az cognitiveservices account show --resource-group $ResourceGroupName --name $ResourceName --query "id" -o tsv
        if (-not $resourceId) {
            Write-Host "Creating the new Immersive Reader resource '$ResourceName' (SKU '$ResourceSKU') in '$ResourceLocation' with subdomain '$ResourceSubdomain'"
            $resourceId = az cognitiveservices account create `
                            --name $ResourceName `
                            --resource-group $ResourceGroupName `
                            --kind ImmersiveReader `
                            --sku $ResourceSKU `
                            --location $ResourceLocation `
                            --custom-domain $ResourceSubdomain `
                            --query "id" `
                            -o tsv
    
            if (-not $resourceId) {
                throw "Error: Failed to create Immersive Reader resource"
            }
            Write-Host "Immersive Reader resource created successfully"
        }
    
        # Create an Microsoft Entra app if it doesn't already exist
        $clientId = az ad app show --id $AADAppIdentifierUri --query "appId" -o tsv
        if (-not $clientId) {
            Write-Host "Creating new Microsoft Entra app"
            $clientId = az ad app create --display-name $AADAppDisplayName --identifier-uris $AADAppIdentifierUri --query "appId" -o tsv
            if (-not $clientId) {
                throw "Error: Failed to create Microsoft Entra application"
            }
            Write-Host "Microsoft Entra application created successfully."
    
            $clientSecret = az ad app credential reset --id $clientId --end-date "$AADAppClientSecretExpiration" --query "password" | % { $_.Trim('"') }
            if (-not $clientSecret) {
                throw "Error: Failed to create Microsoft Entra application client secret"
            }
            Write-Host "Microsoft Entra application client secret created successfully."
    
            Write-Host "NOTE: To manage your Microsoft Entra application client secrets after this Immersive Reader Resource has been created please visit https://portal.azure.com and go to Home -> Microsoft Entra ID -> App Registrations -> (your app) '$AADAppDisplayName' -> Certificates and Secrets blade -> Client Secrets section" -ForegroundColor Yellow
        }
    
        # Create a service principal if it doesn't already exist
        $principalId = az ad sp show --id $AADAppIdentifierUri --query "id" -o tsv
        if (-not $principalId) {
            Write-Host "Creating new service principal"
            az ad sp create --id $clientId | Out-Null
            $principalId = az ad sp show --id $AADAppIdentifierUri --query "id" -o tsv
    
            if (-not $principalId) {
                throw "Error: Failed to create new service principal"
            }
            Write-Host "New service principal created successfully"
    
            # Sleep for 5 seconds to allow the new service principal to propagate
            Write-Host "Sleeping for 5 seconds"
            Start-Sleep -Seconds 5
        }
    
        Write-Host "Granting service principal access to the newly created Immersive Reader resource"
        $accessResult = az role assignment create --assignee $principalId --scope $resourceId --role "Cognitive Services Immersive Reader User"
        if (-not $accessResult) {
            throw "Error: Failed to grant service principal access"
        }
        Write-Host "Service principal access granted successfully"
    
        # Grab the tenant ID, which is needed when obtaining a Microsoft Entra token
        $tenantId = az account show --query "tenantId" -o tsv
    
        # Collect the information needed to obtain a Microsoft Entra token into one object
        $result = @{}
        $result.TenantId = $tenantId
        $result.ClientId = $clientId
        $result.ClientSecret = $clientSecret
        $result.Subdomain = $ResourceSubdomain
    
        Write-Host "`nSuccess! " -ForegroundColor Green -NoNewline
        Write-Host "Save the following JSON object to a text file for future reference."
        Write-Host "*****"
        if($clientSecret -ne $null) {
    
            Write-Host "This function has created a client secret (password) for you. This secret is used when calling Microsoft Entra to fetch access tokens."
            Write-Host "This is the only time you will ever see the client secret for your Microsoft Entra application, so save it now." -ForegroundColor Yellow
        }
        else{
            Write-Host "You will need to retrieve the ClientSecret from your original run of this function that created it. If you don't have it, you will need to go create a new client secret for your Microsoft Entra application. Please visit https://portal.azure.com and go to Home -> Microsoft Entra ID -> App Registrations -> (your app) '$AADAppDisplayName' -> Certificates and Secrets blade -> Client Secrets section." -ForegroundColor Yellow
        }
        Write-Host "*****`n"
        Write-Output (ConvertTo-Json $result)
    }
    
  3. Запустите функцию Create-ImmersiveReaderResource, указав заполнители "<PARAMETER_VALUES>" собственными значениями в соответствии с соответствующими параметрами.

    Create-ImmersiveReaderResource -SubscriptionName '<SUBSCRIPTION_NAME>' -ResourceName '<RESOURCE_NAME>' -ResourceSubdomain '<RESOURCE_SUBDOMAIN>' -ResourceSKU '<RESOURCE_SKU>' -ResourceLocation '<RESOURCE_LOCATION>' -ResourceGroupName '<RESOURCE_GROUP_NAME>' -ResourceGroupLocation '<RESOURCE_GROUP_LOCATION>' -AADAppDisplayName '<MICROSOFT_ENTRA_DISPLAY_NAME>' -AADAppIdentifierUri '<MICROSOFT_ENTRA_IDENTIFIER_URI>' -AADAppClientSecretExpiration '<MICROSOFT_ENTRA_CLIENT_SECRET_EXPIRATION>'
    

    Полная команда выглядит примерно так: Здесь мы помещаем каждый параметр в собственную строку для ясности, чтобы увидеть всю команду. Не следует копировать или использовать эту команду в том виде, в котором она здесь представлена. Скопируйте и используйте команду с собственными значениями. В этом примере имеются фиктивные значения для <PARAMETER_VALUES>объекта . Ваш может отличаться, так как вы придумали собственные имена для этих значений.

    Create-ImmersiveReaderResource
        -SubscriptionName 'MyOrganizationSubscriptionName'
        -ResourceName 'MyOrganizationImmersiveReader'
        -ResourceSubdomain 'MyOrganizationImmersiveReader'
        -ResourceSKU 'S0'
        -ResourceLocation 'westus2'
        -ResourceGroupName 'MyResourceGroupName'
        -ResourceGroupLocation 'westus2'
        -AADAppDisplayName 'MyOrganizationImmersiveReaderAADApp'
        -AADAppIdentifierUri 'api://MyOrganizationImmersiveReaderAADApp'
        -AADAppClientSecretExpiration '2021-12-31'
    
    Параметр Комментарии
    SubscriptionName Имя подписки Azure, которая будет использоваться для вашего ресурса иммерсивного средства чтения. Для создания ресурса необходимо иметь подписку.
    ResourceName Должен быть буквенно-цифровым и может содержаться -, если он - не является первым или последним символом. Длина не может превышать 63 символов.
    ResourceSubdomain Для ресурса иммерсивного средства чтения требуется пользовательский поддомен. Поддомен используется пакетом SDK при вызове службы иммерсивного средства чтения для запуска средства чтения. Поддомен должен быть глобально уникальным. Поддомен должен быть буквенно-цифровым, и может содержать -, если он - не является первым или последним символом. Длина не может превышать 63 символов. Этот параметр является необязательным, если ресурс уже существует.
    ResourceSKU Доступные варианты: S0 (стандартный уровень) или S1 (образование/некоммерческие организации). Дополнительные сведения о каждом доступном номере SKU см . на странице цен на службы искусственного интеллекта Azure. Этот параметр является необязательным, если ресурс уже существует.
    Расположение ресурса Параметры: australiaeast, brazilsouth, canadacentral, centralindia, centralus, eastasia, eastus, eastus2, francecentral, germanywestcentral, japaneast, japanwest, jioindiawest, koreacentral, northcentralus, northeurope, norwayeast, southafricanorth, southcentralus, southeastasia, swedencentral, switzerlandnorth, switzerlandwest, uaenorth, uksouth, westcentralus, westeurope, westus, westus2, westus3. Этот параметр является необязательным, если ресурс уже существует.
    ResourceGroupName Ресурсы создаются в группах ресурсов в рамках подписок. Укажите имя существующей группы ресурсов. Если группа ресурсов еще не существует, создается новая группа ресурсов с этим именем.
    ResourceGroupLocation Если группа ресурсов не существует, необходимо указать расположение, в котором она будет создана. Выполните az account list-locations для получения списка расположений. Используйте свойство Имя (без пробелов) возвращаемого результата. Этот параметр является необязательным, если группа ресурсов уже существует.
    AADAppDisplayName Отображаемое имя приложения Microsoft Entra. Если существующее приложение Microsoft Entra не найдено, создается новый с этим именем. Этот параметр необязателен, если приложение Microsoft Entra уже существует.
    AADAppIdentifierUri Универсальный код ресурса (URI) для приложения Microsoft Entra. Если существующее приложение Microsoft Entra не найдено, создается новый с этим универсальным кодом ресурса (URI). Например, api://MyOrganizationImmersiveReaderAADApp. Здесь мы используем префикс api:// схемы URI Microsoft Entra по умолчанию для совместимости с политикой Microsoft Entra для использования проверенных доменов.
    AADAppClientSecretExpiration Срок действия даты или даты, после которого истекает срок действия секрета клиента приложения Microsoft Entra (пароль) (например, "2020-12-31T11:59:59+00:00" или "2020-12-31". Эта функция создает секрет клиента для вас.

    Чтобы управлять секретами клиента приложения Microsoft Entra после создания этого ресурса, перейдите к портал Azure и перейдите на страницу Home -Microsoft Entra ID ->>Регистрация приложений -> (ваше приложение) [AADAppDisplayName] ->Сертификаты и секреты раздела ">Секреты клиента".

    Screenshot of the Azure portal Certificates and Secrets pane.

  4. Скопируйте выходные данные JSON в текстовый файл для последующего использования. Полученный результат должен выглядеть примерно так:

    {
      "TenantId": "...",
      "ClientId": "...",
      "ClientSecret": "...",
      "Subdomain": "..."
    }
    

Следующий шаг