Azure托管应用程序:如何允许应用程序中的资源使用系统分配的标识相互访问

4urapxun  于 2023-02-09  发布在  其他
关注(0)|答案(2)|浏览(108)

我们使用Azure托管应用程序的方式是为客户提供端到端的解决方案。我们必须能够隐藏知识产权,同时为客户提供良好的解决方案。
托管应用程序资源组中的资源使用拒绝分配进行保护。除了托管应用程序标识本身和在托管应用程序设置期间包含的原则之外,所有原则都拒绝读取以外的任何内容。
例如,在托管应用程序中,我们有:

  • 配置了系统分配的标识的应用程序服务或azure功能,这些应用程序服务应使用系统分配的标识访问同一应用程序中包含的具有写入权限的存储帐户
  • 存储帐户

现在,由于拒绝分配,应用程序服务无法获得任何写入权限,因为新创建的系统分配的身份不在排除的原则列表中。
我找到的唯一方法是使用客户允许的操作来启用存储帐户上的写入权限。
然而,这胜过了向客户提供"黑盒"的目的,因为他现在可以直接访问存储帐户,而不是使用我们提供的API。
目前,我们能够解决这个问题的唯一方法是使用存储键,而不是在托管应用程序中使用系统分配的标识,但这不是一个理想的解决方案。
在安装托管应用程序期间创建的原则是否也可以自动包含在拒绝分配的排除列表中?这样做后,黑盒原则是否仍然有效?
有没有其他办法可以帮我们?
谢谢!

rhfm7lfc

rhfm7lfc1#

我只能确认这个案例是开放的Azure支持,但到目前为止,这个问题还没有解决。托管资源组中的拒绝分配明确指出,写操作只允许管理员主体-其余的是硬阻止的。
目前我认为RBAC在托管应用程序中是不受支持的,在我们的项目中,我们采用了连接字符串等。

new9mtju

new9mtju2#

适用于我们的流程:

  • 创建用户分配的受管身份作为解决方案的一部分。
  • 为其分配托管资源组的所有者角色(请参见下文)。
  • 为您的应用服务和资源分配相同的标识。

棘手的部分是分配初始角色。角色分配固有地在发布者租户中查找将被分配角色的对象。这就是为什么在这个上下文中tenant().tenantId bicep func返回发布者租户,subscription().tenantId返回客户租户(这是部署的作用域)。
要让部署查找用户分配的标识所在的客户租户,您必须使用delegatedManagedIdentityResourceId属性。但是,当部署到自己的租户时(例如,出于测试目的),您不能使用该属性。因此,最好确定您是在自己的租户上部署还是在跨租户场景中,并使用条件。
下面是二头肌的例子:

//however you determine this is fine, but this is an easy way to know if it's being deployed to a different tenant
var crossTenant = tenant().tenantId != subscription().tenantId 
var managedIdentityName = 'whatever-identity-name'

@description('A user assigned managed identity to own the managed resource group and be used by resources within it')
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
  name: 'whatever-identity-name'
  location: 'eastus'
}

@description('This is the built-in Owner role. See https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#owner')
resource ownerRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
  name: '8e3af657-a8ff-443c-a75c-2fe8c4bcb635'
}

resource ownerRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' =  {
  name: guid(subscription().id, managedIdentityName, ownerRoleDefinition.id)
  scope: resourceGroup()
  properties: {
    principalId: managedIdentity.properties.principalId
    roleDefinitionId: ownerRoleDefinition.id
    principalType: 'ServicePrincipal'
    delegatedManagedIdentityResourceId: crossTenant ? managedIdentity.id : null
  }
}

相关问题