1
votes

When I want to get members from graph api from my application graph.windows.net/{aadDirectoryId}/users/{userId.Value}/$links/memberOf?api-version=1.6

I always get

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
} 

When I call this get from https://graphexplorer.azurewebsites.net/ everything is OK.

In azure AD I have set up permissions for api permission

Call code:

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;
            }
}
1
include the calling code..Matt.G
@Patrik Which code flow have you used in calling API?Md Farid Uddin Kiron
You are trying to make use of application permissions by acquiring token using clientid and clientsecret.. I see from the screenshot you have attached that most probably Admin consent is not done.. Directory.Read.All permission requires an admin consent.. So please go and click on Grant admin consent for your directory if you see it at the bottom of your page.. if you don't, then it means you're not an admin and need to ask an Administrator to grant consent for you.. either through portal or by using AdminConsent endpointRohit Saigal
@RohitSaigal, if Admin consent is not given, how does it work in the graphexplorer?Matt.G
@Matt.G and Patrik that's a good question.. answer is that Azure AD Graph Explorer in this case is making use of delegated permissions.. i.e. user's permissions and hence it's not the same.Rohit Saigal

1 Answers

3
votes
  1. Reasoning for Forbidden error and need for Admin Consent

    Looking at the code you have shared to acquire token, you're making use of Application identity, so the permissions required by your application will be application permissions.

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

    enter image description here

    In the screenshot you've attached Directory.Read.All permission for Azure AD Graph is selected but it also says the Admin Consent is not done. If you look at the permission, it clearly says, Admin Consent Required is Yes.

    So resolution for you will be to grant admin consent for required permission. You can do this directly from Azure Portal (same page where you've assigned permissions) if you're logged in as an admin. Another way is to make use of AdminConsent Endpoint

    enter image description here

  2. Why it works for you from https://graphexplorer.azurewebsites.net/

    Azure AD Graph Explorer is making use of Delegated Permissions and calling the API as the user who is logged in so it's working for you. While you're trying to do the same thing from your application, difference being that you're calling with application's identity which doesn't have the permissions consented yet.

  3. Under API permissions only Azure AD Graph API is needed

    In code you have shared, you are only calling https://graph.windows.net so your application only needs permissions to Azure AD Graph API. You can safely remove the permissions assigned for Microsoft Graph API (unless you're using Microsoft Graph API somewhere else in your app)