How to get Microsoft Graph API Access token from Node Script?
Asked Answered
C

4

8

I'd like to use this library to interact with the graph API for my AD - https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/concepts/nodejs.md

However, all of the existing javascript libraries I've found to return access tokens expect a return URL to be passed in, as well as some other web-specific stuff, leading me to believe this is some kind of requirement on Microsoft's end.

Is there any good way to authenticate/receive an access token while running a backend node script (nothing web related) so that I can begin to make calls against the Microsoft Graph API? Thanks in advance for the advice.

Calamine answered 30/5, 2018 at 21:32 Comment(2)
Just for comfirming, do you wan to get token without UI?Prestissimo
@WayneYang-MSFT - yes, that is correct.Calamine
V
9

To run a back-end non-user-authenticated daemon connected to the Graph API, you want to use the app-only authentication flow. Here's a quick summary of the official steps:

  1. Create your Azure AD Tenant. Note the yourtenant.onmicrosoft.com name, and copy this value down.
  2. Register an application through the global Azure Active Directory blade's App Registrations section, not directly within the tenant properties. Copy the Application ID; we'll need it later.
  3. Create a key tied to the registration and remember to copy it down. Once you click out, you can't get the key value back, so make sure to copy it.
  4. Also update the registration's permissions to what you need, click Save, and then also hit the Grant Permissions button.
  5. Make an HTTP request to the login.microsoftonline.com domain to obtain an access token.
  6. Use the access token to make Graph API requests.

Here's a link to Microsofts Node.js example, and here's a link to the direct documentation on the HTTP call to make to retrieve an access token. And here's a super stripped-down example that will output the retrieved access token. Replace the [Tenant], [ApplicationID], and [Key] values:

const request = require("request");

const endpoint = "https://login.microsoftonline.com/[Tenant].onmicrosoft.com/oauth2/token";
const requestParams = {
    grant_type: "client_credentials",
    client_id: "[ApplicationID]",
    client_secret: "[Key]",
    resource: "https://graph.windows.net"
};

request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
    if (err) {
        console.log("error");
    }
    else {
        console.log("Body=" + body);
        let parsedBody = JSON.parse(body);         
        if (parsedBody.error_description) {
            console.log("Error=" + parsedBody.error_description);
        }
        else {
            console.log("Access Token=" + parsedBody.access_token);
        }
    }
});

Once we have the access_token, we can call out to the Graph API. Assuming the apps permissions were configured correctly and applied from step #4, we can start making Graph API requests:

function testGraphAPI(accessToken) {
    request.get({
        url:"https://graph.windows.net/[Tenant]/users?api-version=1.6",
        headers: {
          "Authorization": accessToken
        }
    }, function(err, response, body) {
        console.log(body);
    });
}
Verjuice answered 28/8, 2018 at 20:23 Comment(2)
What exactly am I expected to populate in "client_credentials"? In the example project you sent they didn't explain either, they just referred to docs that weren't so useful.Joinery
@Joinery Sorry it wasn't clear! You literally pass the string "client_credentials". It's not something that you change. This magic string represents the OAuth grant type for a non-user-related authentication. You can read more about this particular OAuth grant type here.Verjuice
F
11

BU0's answer didn't work correctly for me because Microsoft changed their way of using the graph API so I wasn't able to get all the data I needed. Here's how I did it using BU0 answer and this tutorial:

const request = require("request");

const endpoint = "https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token";
const requestParams = {
    grant_type: "client_credentials",
    client_id: "[ApplicationID]",
    client_secret: "[Key]",
    scope: "https://graph.microsoft.com/.default"
};

request.post({ url: endpoint, form: requestParams }, function (err, response, body) {
    if (err) {
        console.log("error");
    }
    else {
        console.log("Body=" + body);
        let parsedBody = JSON.parse(body);
        if (parsedBody.error_description) {
            console.log("Error=" + parsedBody.error_description);
        }
        else {
            console.log("Access Token=" + parsedBody.access_token);
        }
    }
});

function testGraphAPI(accessToken) {
    request.get({
        url:"https://graph.microsoft.com/v1.0/users",
        headers: {
          "Authorization": "Bearer " + accessToken
        }
    }, function(err, response, body) {
        console.log(body);
    });
}
Fetus answered 27/3, 2019 at 14:55 Comment(0)
V
9

To run a back-end non-user-authenticated daemon connected to the Graph API, you want to use the app-only authentication flow. Here's a quick summary of the official steps:

  1. Create your Azure AD Tenant. Note the yourtenant.onmicrosoft.com name, and copy this value down.
  2. Register an application through the global Azure Active Directory blade's App Registrations section, not directly within the tenant properties. Copy the Application ID; we'll need it later.
  3. Create a key tied to the registration and remember to copy it down. Once you click out, you can't get the key value back, so make sure to copy it.
  4. Also update the registration's permissions to what you need, click Save, and then also hit the Grant Permissions button.
  5. Make an HTTP request to the login.microsoftonline.com domain to obtain an access token.
  6. Use the access token to make Graph API requests.

Here's a link to Microsofts Node.js example, and here's a link to the direct documentation on the HTTP call to make to retrieve an access token. And here's a super stripped-down example that will output the retrieved access token. Replace the [Tenant], [ApplicationID], and [Key] values:

const request = require("request");

const endpoint = "https://login.microsoftonline.com/[Tenant].onmicrosoft.com/oauth2/token";
const requestParams = {
    grant_type: "client_credentials",
    client_id: "[ApplicationID]",
    client_secret: "[Key]",
    resource: "https://graph.windows.net"
};

request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
    if (err) {
        console.log("error");
    }
    else {
        console.log("Body=" + body);
        let parsedBody = JSON.parse(body);         
        if (parsedBody.error_description) {
            console.log("Error=" + parsedBody.error_description);
        }
        else {
            console.log("Access Token=" + parsedBody.access_token);
        }
    }
});

Once we have the access_token, we can call out to the Graph API. Assuming the apps permissions were configured correctly and applied from step #4, we can start making Graph API requests:

function testGraphAPI(accessToken) {
    request.get({
        url:"https://graph.windows.net/[Tenant]/users?api-version=1.6",
        headers: {
          "Authorization": accessToken
        }
    }, function(err, response, body) {
        console.log(body);
    });
}
Verjuice answered 28/8, 2018 at 20:23 Comment(2)
What exactly am I expected to populate in "client_credentials"? In the example project you sent they didn't explain either, they just referred to docs that weren't so useful.Joinery
@Joinery Sorry it wasn't clear! You literally pass the string "client_credentials". It's not something that you change. This magic string represents the OAuth grant type for a non-user-related authentication. You can read more about this particular OAuth grant type here.Verjuice
C
0

I had somewhat of an issue for using the url string for the const endpoint

https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token

Instead, I passed tenant in this way instead from Microsoft graph api docs:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize

Reference from docs -> Request an authorization code

Claud answered 14/9, 2019 at 15:22 Comment(0)
A
0

Another way:

'use strict';

const axios = require('axios');
const qs = require('qs');

const accessTokenWithCredentials = (tenantId, clientId, clientSecret, resource) => {
    const data = {
        resource: resource,
        grant_type: 'client_credentials',

    };
    
    return axios({
        url: `https://login.windows.net/${tenantId}/oauth2/token`,
        method: "post",
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        auth: {
        username: clientId,
        password: clientSecret,
        },
        data:  qs.stringify(data)
    }).catch(error => {
        throw error;
    })
};

To call the function:

accessTokenWithCredentials(<tenantId>, <clientId>, <clientSecret>, 'https://graph.microsoft.com').then(response => {
    console.log(`Got access token`);
    const token = JSON.stringify(response.data.access_token);

    // do what you need to do

}).catch(err => {
     console.log("err " + err);
     throw err;
});
Ambiguity answered 21/4, 2021 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.