教程:受媒体服务信任的存储

Media Services logo v3


警告

Azure 媒体服务将于 2024 年 6 月 30 日停用。 有关详细信息,请参阅 AMS 停用指南

在本教程中,学习:

  • 如何为 Azure 媒体服务启用受信任的存储
  • 如何对受信任的存储使用托管标识
  • 如何在使用网络访问控制(如防火墙或 VPN)时授予 Azure 服务访问存储帐户的权限

使用 2020-05-01 API,可以通过将托管标识与媒体服务帐户关联来启用受信任的存储。

注意

受信任的存储仅在 API 中可用,并且当前在 Azure 门户中未启用。

媒体服务可以使用系统身份验证自动访问你的存储帐户。 媒体服务会验证添加关联的用户是否可以使用 Azure 资源管理器 RBAC 访问存储帐户。

跨订阅存储帐户的用法

注意

当媒体服务配置为使用托管标识访问存储时,媒体服务可以使用该托管标识能够访问的任何存储帐户。

对存储使用系统身份验证时,存储帐户必须与媒体服务帐户位于同一个订阅中。 在与媒体服务帐户相同的区域使用存储帐户以避免额外的数据流出量成本。

对于这两种身份验证类型,创建或更新媒体服务帐户的主体必须对存储帐户拥有“Microsoft.Storage/storageAccounts/listkeys/action”权限。

概述

重要

将 2020-05-01 API 用于所有对媒体服务的请求。

下面是为媒体服务创建受信任存储的一般步骤:

  1. 创建资源组。
  2. 创建存储帐户。
  3. 轮询存储帐户,直到它准备就绪。 当存储帐户准备就绪时,请求将返回服务主体 ID。
  4. 查找“存储 Blob 数据参与者”角色的 ID。
  5. 调用授权提供程序并添加角色分配。
  6. 更新媒体服务帐户,以便使用托管标识向存储帐户进行身份验证。
  7. 如果你不想继续使用这些资源并为其付费,请将其删除。

先决条件

需要有一个 Azure 订阅才能开始。 如果没有 Azure 订阅,请创建一个试用帐户

获取租户 ID 和订阅 ID

如果不知道如何获取租户 ID 和订阅 ID,请参阅如何查找订阅和租户 ID

创建服务主体和机密

如果不知道如何创建服务主体和机密,请参阅获取访问媒体服务 API 的凭据

使用 REST 客户端

此脚本旨在用于 REST 客户端,例如 Visual Studio code 扩展中提供的客户端。 针对开发环境对其进行调整。

设置初始变量

此脚本的这一部分用于 REST 客户端。 可以在你的开发环境中以其他方式使用变量。

### AAD details
@tenantId = your tenant ID
@servicePrincipalId = the service principal ID
@servicePrincipalSecret = the service principal secret

### AAD resources
@armResource = https%3A%2F%2Fmanagement.core.chinacloudapi.cn%2F
@graphResource = https%3A%2F%2Fgraph.chinacloudapi.cn%2F
@storageResource = https%3A%2F%2Fstorage.azure.com%2F

### Service endpoints
@armEndpoint = management.chinacloudapi.cn
@graphEndpoint = graph.chinacloudapi.cn
@aadEndpoint = login.partner.microsoftonline.cn

### ARM details
@subscription = your subscription id
@resourceGroup = the resource group you'll be creating
@storageName = the name of the storage you'll be creating
@accountName = the name of the account you'll be creating
@resourceLocation = China East 2 (or the location that works best for your region)

获取 Azure 资源管理器的令牌

// @name getArmToken
POST https://{{aadEndpoint}}/{{tenantId}}/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded

resource={{armResource}}&client_id={{servicePrincipalId}}&client_secret={{servicePrincipalSecret}}&grant_type=client_credentials

获取 Graph API 的令牌

此脚本的这一部分用于 REST 客户端。 可以在你的开发环境中以其他方式使用变量。

// @name getGraphToken
POST https://{{aadEndpoint}}/{{tenantId}}/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded

resource={{graphResource}}&client_id={{servicePrincipalId}}&client_secret={{servicePrincipalSecret}}&grant_type=client_credentials

获取服务主体详细信息

// @name getServicePrincipals
GET https://{{graphEndpoint}}/{{tenantId}}/servicePrincipals?$filter=appId%20eq%20'{{servicePrincipalId}}'&api-version=1.6
x-ms-client-request-id: cae3e4f7-17a0-476a-a05a-0dab934ba959
Authorization:  Bearer {{getGraphToken.response.body.access_token}}

存储服务主体 ID

@servicePrincipalObjectId = {{getServicePrincipals.response.body.value[0].objectId}}

创建资源组

// @name createResourceGroup
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}
    ?api-version=2016-09-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
    "location": "{{resourceLocation}}"
}

创建存储帐户

// @name createStorageAccount
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}
    ?api-version=2019-06-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
    "sku": {
    "name": "Standard_GRS"
    },
    "kind": "StorageV2",
    "location": "{{resourceLocation}}",
    "properties": {
    }
}

获取存储帐户状态

存储帐户将需要一段时间才能准备就绪,因此该请求会轮询其状态。 重复此请求,直到存储帐户准备就绪。

// @name getStorageAccountStatus
GET {{createStorageAccount.response.headers.Location}}
Authorization: Bearer {{getArmToken.response.body.access_token}}

获取存储帐户详细信息

存储帐户准备就绪后,获取存储帐户的属性。

// @name getStorageAccount
GET https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}
    ?api-version=2019-06-01
Authorization: Bearer {{getArmToken.response.body.access_token}}

获取 ARM 的令牌

// @name getStorageToken
POST https://{{aadEndpoint}}/{{tenantId}}/oauth2/token
Accept: application/json
Content-Type: application/x-www-form-urlencoded

resource={{storageResource}}&client_id={{servicePrincipalId}}&client_secret={{servicePrincipalSecret}}&grant_type=client_credentials

使用系统分配的托管标识创建媒体服务帐户

// @name createMediaServicesAccount
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaservices/{{accountName}}?api-version=2020-05-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
  "identity": {
      "type": "SystemAssigned"
  },
  "properties": {
    "storageAccounts": [
      {
        "id": "{{getStorageAccountStatus.response.body.id}}"
      }
    ],
    "encryption": {
      "type": "SystemKey"
    }
  },
  "location": "{{resourceLocation}}"
}

获取存储 Blob 数据角色定义

// @name getStorageBlobDataContributorRoleDefinition
GET https://management.chinacloudapi.cn/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}/providers/Microsoft.Authorization/roleDefinitions?$filter=roleName%20eq%20%27Storage%20Blob%20Data%20Contributor%27&api-version=2015-07-01
Authorization: Bearer {{getArmToken.response.body.access_token}}

设置存储角色分配

角色分配指出,媒体服务帐户的服务主体具有存储角色“存储 Blob 数据参与者”。 这可能需要一些时间,因此请务必等待,否则媒体服务帐户将无法正确设置。

PUT https://management.chinacloudapi.cn/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}/providers/Microsoft.Authorization/roleAssignments/{{$guid}}?api-version=2020-04-01-preview
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
  "properties": {
    "roleDefinitionId": "/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}/providers/Microsoft.Authorization/roleDefinitions/{{getStorageBlobDataContributorRoleDefinition.response.body.value[0].name}}",
    "principalId": "{{createMediaServicesAccount.response.body.identity.principalId}}"
  }
}

为托管标识提供对存储帐户的旁路访问权限

此操作会将访问权限从系统管理的标识更改为托管标识。 这样,存储帐户就可以通过防火墙访问存储帐户,因为无论 IP 访问规则 (ACL) 如何,Azure 服务都可以访问存储帐户。

请再次等待,直到在存储帐户中分配了角色,否则将无法正确设置媒体服务帐户。

// @name setStorageAccountFirewall
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}
    ?api-version=2019-06-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
    "sku": {
    "name": "Standard_GRS"
    },
    "kind": "StorageV2",
    "location": "{{resourceLocation}}",
    "properties": {
      "minimumTlsVersion": "TLS1_2",
      "networkAcls": {
        "bypass": "AzureServices",
        "virtualNetworkRules": [],
        "ipRules": [],
        "defaultAction": "Deny"
      }
    }
}

更新媒体服务帐户以使用托管标识

由于存储角色分配可能需要几分钟才能传播,因此可能需要重试几次此请求。

// @name updateMediaServicesAccountWithManagedStorageAuth
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaservices/{{accountName}}?api-version=2020-05-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
  "identity": {
      "type": "SystemAssigned"
  },
  "properties": {
    "storageAccounts": [
      {
        "id": "{{getStorageAccountStatus.response.body.id}}"
      }
    ],
    "storageAuthentication": "ManagedIdentity",
    "encryption": {
      "type": "SystemKey"
    }
  },
  "location": "{{resourceLocation}}"
}

测试访问权限

通过在存储帐户中创建资产来测试访问权限。

// @name createAsset
PUT https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaservices/{{accountName}}/assets/testasset{{index}}withoutmi?api-version=2018-07-01
Authorization: Bearer {{getArmToken.response.body.access_token}}
Content-Type: application/json; charset=utf-8

{
}

删除资源

如果你不想保留已创建的资源并继续为其付费,请将其删除。

### Clean up the Storage account
DELETE https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Storage/storageAccounts/{{storageName}}
    ?api-version=2019-06-01
Authorization: Bearer {{getArmToken.response.body.access_token}}

### Clean up the Media Services account
DELETE https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaservices/{{accountName}}?api-version=2020-05-01
Authorization: Bearer {{getArmToken.response.body.access_token}}

### Clean up the Media Services account
GET https://{{armEndpoint}}/subscriptions/{{subscription}}/resourceGroups/{{resourceGroup}}/providers/Microsoft.Media/mediaservices/{{accountName}}?api-version=2020-05-01
Authorization: Bearer {{getArmToken.response.body.access_token}}