图形 API - 权限不足以完成操作。

51
尝试使用时,访问 Graph 服务客户端时遇到以下错误:

Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.

在研究了这个错误之后,最常见的解决方案是设置 API 的权限。但这已经完成,并已具有读取基本/完整配置文件的权限。
我已删除并重新添加了 API。
以下是我AzureAuthenticationProvider类中继承自IAuthenticationProvider的代码:
public class AzureAuthenticationProvider : IAuthenticationProvider
{
    private string _azureDomain = "myDevDom.onmicrosoft.com";

    public async Task AuthenticateRequestAsync(HttpRequestMessage request)
    {
        try
        {
            string clientId = "2b823c67-1b0d-4a10-a9e1-737142516f5q";
            string clientSecret = "xxxxxx";

            AuthenticationContext authContext = new AuthenticationContext("https://login.windows.net/" + _azureDomain + "/oauth2/token");

            ClientCredential credentials = new ClientCredential(clientId, clientSecret);

            AuthenticationResult authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", credentials);

            request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
        }
        catch (Exception ex)
        {
        }
    }
}

我尝试将客户端密钥更改为无效的ID,它抛出了一个错误,因此客户端密钥是正确的。我还尝试验证访问令牌是否有效,通过更改访问令牌,同样返回错误。

上面的代码似乎正常工作。

以下是我尝试访问Azure AD的代码:

public async Task<IGraphServiceUsersCollectionPage> GetUsersByLastName(string lastname)  
{
    GraphServiceClient graphClient = new GraphServiceClient(new AzureAuthenticationProvider());
    string filter = String.Format("startswith(surname, '{0}')", lastname);
    IGraphServiceUsersCollectionPage users = await graphClient.Users.Request().Filter(filter).GetAsync(); //Fails on this line
    return users;
}

azureADpermissionProperties


感谢您的建议。在应用程序权限下,我选择了“读取和写入目录数据”,在委派权限下,我选择了“登录并读取用户配置文件”、“读取所有用户基本配置文件”和“访问以已登录用户身份访问目录”。虽然在开发应用程序中,我已选择所有可用选项进行测试,但仍然出现身份验证错误。 - j9070749
3
这个 API 调用与委派权限无关。你正在进行一个仅限应用的调用(指定客户端 ID 和密钥)。你是否也授予权限?你可以在 jwt.io 上检查访问令牌的内容。 - juunas
1
@juunas,我同意关于委派权限的观点。我已经将应用程序权限(用于读取和写入目录数据)设置在此之上 - 我只是用截图剪切了标题。在尝试授予权限时,我收到一个错误提示:“无法为应用程序授予权限”。我猜这可能是问题所在?感谢您的帮助。 - j9070749
@juunas .... 不,我目前正在一个新的Azure AD上进行测试,我是管理员,权限保存后需要多长时间才能应用? - j9070749
1
有时可能需要几分钟。了解最好的方法是在jwt.io中检查访问令牌。具体来说,查看令牌中的范围。您应该在其中拥有类似于Directory.ReadWrite.All的内容。 - juunas
显示剩余2条评论
12个回答

21
请参考以下步骤:
  1. 从您的截图中看来,似乎您已经授予了应用程序Windows Azure Active Directory(Azure AD Graph API)的读取和写入目录数据权限。由于您正在使用Microsoft Graph(https://graph.microsoft.com/),因此您需要授予应用程序Microsoft Graph的权限: enter image description here

  2. 由于您是AAD中的管理员,您可以点击上面截图中显示的授予权限按钮,为组织中的用户授予权限。

  3. 然后,您可以使用您的代码(客户端凭据流程)并查询用户信息。如果您检查由Azure AD签发的访问令牌中的声明,您可以在roles声明中找到Directory.Read.All权限。


1
感谢您的帮助。很抱歉截图造成了困惑,但实际上我已经授予了Microsoft Graph的权限。我认为问题可能是我不是管理员,虽然我已经选择了应用程序的权限,但我无法授予权限(我收到一个错误提示“无法为应用程序授予权限”)。我目前正在测试这个问题,在Azure AD上我是管理员。再次感谢您的建议。 - j9070749

16

授予权限 请确保点击"授予权限",然后为所有用户账户选择"是"。


13

在我的情况下,删除用户功能无法正常工作。我采取了以下步骤,然后它开始为我工作。

进入 Azure活动目录 > 角色和管理员 > 点击“用户管理员” > 点击“+添加分配”以添加您的应用程序。(即使用AAD Graph REST API与Azure活动目录进行交互的控制台应用程序)。

希望对某些人有所帮助。


这对我解决了问题。我原以为拥有全局管理员权限就足够了,但还需要添加用户管理员权限。 - Jakob
是的!我一直在想如何给我的应用分配这些权限,就像我知道设置API权限是不够的一样!对我来说解决了,谢谢! - undefined
太棒了!这对我来说完美地运作了! 但是应用程序没有出现在“全部”下的起始列表中。我不得不粘贴我的应用程序的客户端ID。 - undefined

8
对我来说解决这个问题的关键是提示:
要使用Graph API与您的B2C租户一起使用,您需要通过在Azure门户中使用通用的应用程序注册菜单(所有服务,默认情况下不是收藏夹)注册专用应用程序,而不是Azure AD B2C的应用程序菜单。 您无法重复使用在Azure AD B2C的应用程序菜单中注册的已经存在的B2C应用程序。
在页面AD B2C API access demo中了解更多信息。

3
在某些情况下,实际问题是因为我们使用了“应用程序权限”而不是“委派权限”。在我的应用程序中,我尝试列出所有具有应用程序权限的用户,但它没有起作用。当我切换到委派权限后,它就起作用了。
所以,一些快速检查如下:
  1. 检查您是否正在使用Microsoft Graph API或其他内容
  2. 使用委派权限
  3. 单击授予权限按钮以传播权限 :)
希望这能帮助某些人。

2

假设您想在Azure Active Directory中创建组,我需要执行以下步骤来解决此问题:

  1. AD > 应用注册 > 您的应用
  2. 选择所需权限
  3. 单击添加并选择Microsoft Graph并添加它
  4. 选择Microsoft Graph
  5. 从委派权限列表中选择读取和写入所有组
  6. 保存
  7. 选择Windows Azure Active Directory并授予所有应用程序权限
  8. 保存

1

仅勾选“Directory.Read.All/Write”无法授予权限。

我遇到了同样的问题,并通过将服务主体添加到管理员角色来解决。

如果您的应用程序是最近创建的,则可以使用Azure AD Powershell完成此操作。

$pricinple = Get-AzureADServicePrincipal || Where-Object {$_.DisplayName -eq 'youappname'}

 $role = Get-AzureADDirectoryRole | Where-Object {$_.displayName -eq 'Company Administrator'}

Add-AzureADDirectoryRoleMember -ObjectId $role.ObjectId -RefObjectId $pricinple.ObjectId

详细信息请参见https://learn.microsoft.com/en-us/powershell/module/Azuread/Add-AzureADDirectoryRoleMember?view=azureadps-2.0

如果您的应用程序是很久以前创建的,则需要使用MSOnline。 请参见:https://learn.microsoft.com/en-us/powershell/module/msonline/Add-MsolRoleMember?view=azureadps-1.0


你不需要这样做 - 如果你给它全局管理员权限只是为了读取用户信息,那就像用大锤子来打钉子一样过度了。 - LeeM
虽然我同意@LeeM的观点,但这实际上是使其正常工作的唯一方法。在我能找到的Microsoft文档中没有提到过。谢谢Langy。 - whites11
这只是给后来的读者提供信息,但重要的是要确定需要全局管理员权限的确切内容。您可能需要GA最初授予应用程序标识适当的用户权限。之后,仅需读取用户属性,应用程序就不需要GA。即使授予用户管理员权限也更好,但如果应用程序没有进行写操作,则应将其作为解决问题的一部分。几乎所有基于用户的管理任务都不需要GA。当然,对于我管理的任何任务,包括用户/邮箱/组创建、MFA/SSPR等,都不需要GA。 - LeeM

1

前往Azure门户->活动目录->应用注册->选择您的应用程序->API权限

现在,点击添加权限并选择Microsoft Graph,选择应用程序权限并搜索User.Read.All

将这些权限添加到您的应用程序中,它应该可以正常工作。


1

1

这篇答案是给那些直接尝试使用API的人。

一旦您添加了所需的权限,您将需要重新生成访问令牌。我添加了以下权限(可能比我们实际需要的更多,但现在它可以工作)。enter image description here

添加完权限后,我使用以下命令生成了新的访问令牌:

curl -X POST "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "client_id=535fb089-9ff3-47b6-9bfb-4f1264799865" \
     -d "scope=https%3A%2F%2Fgraph.microsoft.com%2F.default" \
     -d "client_secret=qWgdYAmab0YSkuL1qKv5bPX" \
     -d "grant_type=client_credentials"

然后在 API 中像下面这样使用:

curl -X GET "https://graph.microsoft.com/v1.0/users" \
     -H "Authorization: Bearer {access-token}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接