【问题标题】:Azure AD Graph api returns ForbiddenAzure AD Graph api 返回 Forbidden
【发布时间】:2019-03-06 13:58:31
【问题描述】:

当我想从我的应用程序中获取来自 graph api 的成员时 graph.windows.net/{aadDirectoryId}/users/{userId.Value}/$links/memberOf?api-version=1.6

我总是得到

Response: StatusCode: 403, ReasonPhrase: 'Forbidden', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Pragma: no-cache
  ocp-aad-diagnostics-server-name: aVvd1R49Sg=
  request-id: 67105ddc-2b5f-84bf-7ec43a4d3117
  client-request-id: fb1ef66f-451357f08975abd4
  x-ms-dirapi-data-contract-version: 1.6
  ocp-aad-session-key: _XjEM7ooA1Emw_l6FjiyMwKqtoEPSWgxw-04c_nX785foVv6fGM_lBejApG_gJW2fXC_LBNrZRJRryuBIOO7_O1bF2oEEiWMvnW9Ywx71OP0NJ5gRyZDGlLyNsjmsDvu.42WXAH4v8FjbaSNvNtH1Nnkm3z5on0J5ZsptMguA52A
  DataServiceVersion: 3.0;
  Strict-Transport-Security: max-age=31536000; includeSubDomains
  Access-Control-Allow-Origin: *
  Duration: 853533
  Cache-Control: no-cache
  Date: Tue, 05 Mar 2019 14:01:17 GMT
  Server: Microsoft-IIS/10.0
  X-AspNet-Version: 4.0.30319
  X-Powered-By: ASP.NET
  Content-Length: 219
  Content-Type: application/json; odata=minimalmetadata; streaming=true; charset=utf-8
  Expires: -1
} 

当我从https://graphexplorer.azurewebsites.net/ 调用此 get 时,一切正常。

在 azure AD 中,我设置了权限 api permission

调用代码:

private static List<string> GetGroupsFromGraphAPI(ClaimsIdentity claimsIdentity)
        {
            _logger.Info($"Getting claims from Graph API for {claimsIdentity.Name}.");

            List<string> groupObjectIds = new List<string>();

            var aadClientId = ConfigurationManager.AppSettings["ida:ClientId"];
            var aadSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
            var aadDirectoryId = ConfigurationManager.AppSettings["ida:DirectoryId"];

            ClientCredential credential = new ClientCredential(aadClientId, aadSecret);
            AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/" + aadDirectoryId);
            string accessToken;
            try
            {
                _logger.Info($"Client ID: {aadClientId}");
                _logger.Info($"Secret: {aadSecret}");
                _logger.Info($"Directory id: {aadDirectoryId}");

                var token = authContext.AcquireToken("https://graph.windows.net", credential);
                _logger.Info($"Token: {token.ToString()}");
                accessToken = token.AccessToken;
                _logger.Info($"Get access token {accessToken}");
            }
            catch
            {
                _logger.Error("Cannot aquire token for Graph API.");
                throw;
            }

            var userId = claimsIdentity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier");
            if (userId == null)
            {
                _logger.Warn($"No user ID to get group membership for. ({claimsIdentity.Name})");
                return groupObjectIds;
            }

            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            HttpResponseMessage response;
            try
            {
                var link =
                    $"https://graph.windows.net/{aadDirectoryId}/users/{userId.Value}/$links/memberOf?api-version=1.6";
                _logger.Info($"GetAsync {link}");
                response = client.GetAsync(link).Result;
            }
            catch
            {
                _logger.Error("Failed to load group membership for " + claimsIdentity.Name);
                throw;
            }
}

【问题讨论】:

  • 包括调用代码..
  • @Patrik 调用 API 时使用了哪些代码流?
  • 您正试图通过使用 clientid 和 clientsecret 获取令牌来利用应用程序权限。我从您附上的屏幕截图中看到,很可能 未完成管理员同意。 . Directory.Read.All 权限需要管理员同意.. 所以如果你在页面底部看到Grant admin consent for your directory,请点击它.. 如果你没有,那么这意味着你不是管理员,需要请管理员为您授予同意.. 通过门户或使用 AdminConsent 端点
  • @RohitSaigal,如果没有得到管理员的同意,它在 graphexplorer 中是如何工作的?
  • @Matt.G 和 Patrik,这是一个很好的问题.. 答案是 Azure AD Graph Explorer 在这种情况下正在使用delegated permissions.. 即用户的权限,因此它不一样。

标签: c# azure azure-active-directory azure-ad-graph-api


【解决方案1】:
  1. Forbidden 错误的原因和需要管理员同意

    查看您共享的获取令牌的代码,您正在使用应用程序身份,因此您的应用程序所需的权限将是应用程序权限。

        ClientCredential credential = new ClientCredential(aadClientId, aadSecret);
        AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/" + aadDirectoryId);  
        ...
        var token = authContext.AcquireToken("https://graph.windows.net", credential);
    

    在您附加的屏幕截图中,Directory.Read.All 选择了 Azure AD Graph 的权限,但它也表示未完成管理员同意。如果您查看权限,它清楚地表明,需要管理员同意是。

    因此,您的解决方案是授予管理员对所需权限的同意。如果您以管理员身份登录,则可以直接从 Azure 门户(分配权限的同一页面)执行此操作。另一种方法是使用 AdminConsent Endpoint

  2. 为什么它对您有用 https://graphexplorer.azurewebsites.net/

    Azure AD Graph Explorer 正在使用Delegated Permissions 并以登录用户的身份调用 API,因此它可以为您工作。当您尝试从您的应用程序中执行相同的操作时,不同之处在于您使用尚未获得许可的应用程序身份进行调用。

  3. 在 API 权限下,仅需要 Azure AD Graph API

    在您共享的代码中,您只调用了https://graph.windows.net,因此您的应用程序只需要Azure AD Graph API 的权限。您可以安全地删除分配给 Microsoft Graph API 的权限(除非您在应用程序的其他位置使用 Microsoft Graph API)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    相关资源
    最近更新 更多