【问题标题】:Azure AD Groups and User Assigned Managed IdentitiesAzure AD 组和用户分配的托管标识
【发布时间】:2020-07-10 04:27:28
【问题描述】:

如何允许用户分配的托管身份 (UAMI) 对 Azure AD 组进行读写? 我有一个作为 UMAI 运行的 .Net Core 3.1 Azure Function 应用程序。该应用程序需要能够 R/W Azure AD 组。我的代码通过笔记本电脑上的应用注册服务主体运行。在 Azure 中,UAMI 是订阅参与者,并且与 FunctionApp 相关联。

这适用于本地和 Azure:

        var azureFluentClient = AzureAuthenticator.AzureFluentClient(context._ILogger, context.ExecutionContext,context.Settings);
        var resourceGroups = await azureFluentClient.ResourceGroups.ListAsync();

在本地工作,在 Azure 上失败:

        var azureFluentClient = AzureAuthenticator.AzureFluentClient(context._ILogger, context.ExecutionContext, context.Settings);
        var groups = await azureFluentClient.AccessManagement.ActiveDirectoryGroups.GetByNameAsync("AAA1");

错误:

{"odata.error":{"code":"Authorization_RequestDenied","message":{"lang":"en","value":"Insufficient privileges to complete the operation."},"requestId":"f797cb42-a75d-48d9-a902-c580955800cd","date":"2020-07-10T05:41:59"}}

ex.Response.Content: "Insufficient privileges to complete the operation."

Microsoft.Azure.Management.Graph.RBAC.Fluent.Models.GraphErrorException: Operation returned an invalid status code 'BadRequest'
   at Microsoft.Azure.Management.Graph.RBAC.Fluent.GroupsOperations.ListWithHttpMessagesAsync(ODataQuery`1 odataQuery, Dictionary`2 customHeaders, CancellationToken cancellationToken)
   at Microsoft.Azure.Management.Graph.RBAC.Fluent.GroupsOperationsExtensions.ListAsync(IGroupsOperations operations, ODataQuery`1 odataQuery, CancellationToken cancellationToken)
   at Microsoft.Azure.Management.Graph.RBAC.Fluent.ActiveDirectoryGroupsImpl.<ListAsync>b__7_0(CancellationToken cancellation)
   at Microsoft.Azure.Management.ResourceManager.Fluent.Core.PagedCollection`2.LoadPageWithWrapModelAsync(Func`2 listInnerAsync, Func`3 listInnerNext, Func`3 wrapModelAsync, Boolean loadAllPages, CancellationToken cancellationToken)
   at Microsoft.Azure.Management.ResourceManager.Fluent.Core.PagedCollection`2.LoadPage(Func`2 listInnerAsync, Func`3 listInnerNext, Func`2 wrapModel, Boolean loadAllPages, CancellationToken cancellationToken)
   at Microsoft.Azure.Management.Graph.RBAC.Fluent.ActiveDirectoryGroupsImpl.ListAsync(Boolean loadAllPages, CancellationToken cancellationToken)
   at HDIManagement.FunctionApp.API.TestServiceConfiguration.TestADGroupAccess(OperationsContext context) in C:\Users\josep\source\repos\HDI\BareMetal\HDI-Logging\HDIManagement.FunctionApp\API\TestConfiguration.cs:line 67

不同之处在于有一个用于本地运行的应用注册,它具有 API 权限:Azure Active Directory Graph/Directory.ReadWrite.All。我认为问题在于没有与 UAMI 关联的应用注册,因此无法授予权限。

【问题讨论】:

    标签: c# azure azure-active-directory azure-functions azure-web-app-service


    【解决方案1】:

    是的,用户分配的身份是不与 AD 应用关联的服务主体。

    在这种情况下,如果您想授予 Azure AD 组的 R/W 权限,您可以直接将管理员角色 Groups administrator 授予它。

    导航到门户中的Azure Active Directory -> Roles and administrators -> 选择Groups administrator -> Add assignments -> 搜索身份名称并添加。

    【讨论】:

    • 生产环境中永远不允许使用管理员价格
    • @jlo-gmail 如果是这样,没有其他办法。除非您使用自己的广告应用程序,否则您可以授予api权限。顺便说一句,我认为Directoy.Readwrite.All不仅仅是组管理员,为什么会允许?
    【解决方案2】:

    解决方案: FunctionApp 的用户分配托管身份 (UAMI) 要求

    • 分配 UAMI 订阅贡献者角色(我的代码不仅仅是查找 AAD 组)
    • 分配 UAMI AD 目录读取者角色(在生产环境中可接受)
    • 将 UAMI 添加为 AD 组的所有者以进行操作(添加/删除成员)

    请注意,UAMI 将无法创建、分配、删除或管理任何未通过所有权明确授予权限的 AD 组。

    由于 AD 延迟/缓存对托管身份所做的更改(更改可能需要一段时间才会出现,把我骗进兔子洞),我花了很多时间。 我写了这个脚本来帮助确定我的 FunctionApp 的实际要求。运行此脚本后,我运行我的 FunctionApp 测试方法。由于 Identity 每次都是新的,因此没有缓存或延迟实现。

    Connect-AzureRmAccount -TenantId $tenantId
    Connect-AzureAD -TenantId $tenantId
    
    Set-AzureRmContext  -TenantId $tenantId -SubscriptionId $subscriptionId
    
    #Drops/recreates manged Identity
    Set-AzureRmWebApp -AssignIdentity $false -ResourceGroupName "rg01" -Name "fa01" 
    Set-AzureRmWebApp -AssignIdentity $true -ResourceGroupName "rg01" -Name "fa01" 
    
    $current = Get-AzureRmWebApp -ResourceGroupName "rg01" -Name "fa01"
    $objectId = $current.Identity.PrincipalId
    
    #Add functionApp Identity to Contributor
    $role = Get-AzureRmRoleDefinition -Name "Contributor"
    New-AzureRMRoleAssignment -ObjectId $objectId -RoleDefinitionName "Contributor"  -Scope "/subscriptions/{subscription guid}"
    
    #Assign functionApp Identity to AD Role 'Directory Readers'
    $roleDefinition = Get-AzureADMSRoleDefinition -Filter "displayName eq 'Directory Readers'"
    $roleAssignment = New-AzureADMSRoleAssignment  -RoleDefinitionId $roleDefinition.Id -PrincipalId $objectId  -ResourceScope "/"
    
    #Assign functionApp Identity to AD Group
    $group = Get-AzureADGroup  -Filter "DisplayName eq  'adgroup01'"
    Add-AzureADGroupOwner -ObjectId $group.ObjectId -RefObjectId $objectId
    

    【讨论】:

    • 那么为什么你没有说你只想在你的问题中对特定的组进行操作?如果是这样,显然该组的所有者就足够了。
    • 您不需要 Groups Administrator 来执行 ListAsync,只需要 Directory Readers。
    • 那么为什么不通过对象 id 添加组呢?如果你给目录阅读器,它可以读取目录中的所有东西,我记得你说过在生产中永远不允许管理员价格?它也是一个管理员角色。
    猜你喜欢
    • 2022-01-18
    • 2022-11-11
    • 2022-11-10
    • 2022-07-07
    • 2021-01-28
    • 2021-10-17
    • 2019-09-19
    • 2022-10-24
    • 2021-08-31
    相关资源
    最近更新 更多