0
votes

I'm trying to use NodeJs access some details of the Azure AD. I can get an access token OK, however whenever I try to call anything using the Graph API (in this case just a list of all groups) it says that I have "Insufficient privileges to complete the operation."

I've gone into the app in AD and added all permissions (just to make sure) and I still get this error - Have I missed something? Here is my code:

var msRestAzure = require('ms-rest-azure');
var graphRbacManagementClient = require('azure-graph');
var tenantId='';
// Enter your tenant ID here which can be found from your Azure AD URL
// Eg. https://manage.windowsazure.com/example.com#Workspaces/ActiveDirectoryExtension/Directory/<TenantId>/users

var clientId = ''
var clientSecret = ''

console.log('Starting');

msRestAzure.loginWithServicePrincipalSecret(clientId, clientSecret, tenantId, { tokenAudience: 'graph' }, function (err, credentials, subscriptions) {
    if(err){
        console.log('Could not get token', err)
    }

    console.log('Logged In');

    var client = new graphRbacManagementClient(credentials, tenantId);

    console.log("Client created");

    client.groups.list({}, function(err, result){
        if(err){
            console.log('Could not list groups', err)
        }
    })
});

The error returned is:

{
    "statusCode": 403,
    "request": {
        "rawResponse": false,
        "queryString": {

        },
        "method": "GET",
        "headers": {
            "x-ms-client-request-id": "2b0e7464-bf4f-41d3-8440-38797bf0d72b",
            "accept-language": "en-US",
            "Content-Type": "application/json; charset=utf-8"
        },
        "url": "https://graph.windows.net/5a677fc4-23da-4e7a-a0fa-75f2c53e9c90/groups?api-version=1.6",
        "body": null
    },
    "response": {
        "body": "{\"odata.error\":{\"code\":\"Authorization_RequestDenied\",\"message\":{\"lang\":\"en\",\"value\":\"Insufficient privileges to complete the operation.\"}}}",
        "headers": {
            "cache-control": "no-cache",
            "pragma": "no-cache",
            "content-type": "application/json;odata=minimalmetadata;streaming=true;charset=utf-8",
            "expires": "-1",
            "server": "Microsoft-IIS/8.5",
            "ocp-aad-diagnostics-server-name": "F3xU7bkLCvTOf62bCyNdsiLFnuyfFODP68vB9RmoAS0=",
            "request-id": "f8404560-e300-4cd1-8a4b-a6487b06f7a2",
            "client-request-id": "97cd97fa-448f-44bb-87dc-7d48505e80db",
            "x-ms-dirapi-data-contract-version": "1.6",
            "ocp-aad-session-key": "REMOVED",
            "x-content-type-options": "nosniff",
            "dataserviceversion": "3.0;",
            "strict-transport-security": "max-age=31536000; includeSubDomains",
            "access-control-allow-origin": "*",
            "x-aspnet-version": "4.0.30319",
            "x-powered-by": "ASP.NET, ASP.NET",
            "duration": "1097838",
            "date": "Wed, 05 Oct 2016 14:10:41 GMT",
            "connection": "close",
            "content-length": "139"
        },
        "statusCode": 403
    },
    "body": {
        "code": "Authorization_RequestDenied",
        "message": "Insufficient privileges to complete the operation."
    }
}

For testing I've added all permissions to both graph and azure AD to this client:

enter image description here

2
Can you post the full error message (including the correlation ID and the time stamp)? Can you also post a screenshot of the permissions you configured your app to have? - Philippe Signoret
Added in the complete error message - can't find a correlation id anywhere, how can I find that? - smuff
Have you checked whether running the exact same thing outside of Azure Functions works? If not, then you can simplify your question by removing all references to Azure Functions. - David Ebbo
Apologies, I forget that Azure AD Graph API responses don't include that in the error message body. I was looking for the request-id header. - Philippe Signoret
Can you also include a screenshot of which permissions you've configured for the application? - Philippe Signoret

2 Answers

3
votes

Just because you've selected the permissions in the Azure Portal doesn't mean your app has been granted them. I'd recommend decoding the token you're sending to AAD Graph using a JWT decoder like calebb.net. The token's scp or roles claim should contain the necessary permission, in this case, Groups.Read.All.

If the token is missing Groups.Read.All, you'll need to get a tenant administrator to "consent" to the application using the prompt=admin_consent parameter described here. This will grant your application the permissions you've requested.

If the token contains the Groups.Read.All permission, you should let us know because that would be a bug in the Graph API.

0
votes

To able to call the specific REST API, we need to ensure that sufficient privileges. The Group REST require the users who sign-in has the permission to use.

There are two kinds of scopes, app-only or delegated. App-only scopes (also known as app roles) grant the app the full set of privileges offered by the scope. App-only scopes are typically used by apps that run as a service without a signed-in user being present.

Delegated permission scopes are for apps that act on behalf of a user. These scopes delegate the privileges of the signed-in user, allowing the app to act as the user. The actual privileges granted to the app will be the least privileged combination (the intersection) of the privileges granted by the scope and those possessed by the signed-in user. For example, if the permission scope grants delegated privileges to write all directory objects, but the signed-in user has privileges only to update their own user profile, the app will only be able to write the signed-in user's profile but no other objects.

This specification is the document about Microsoft Graph, however it should also apply to other Microsoft Service.