I'm trying to write a simple Azure Function that calls the Microsoft Graph API. But I could not make the access_token work. Here is what I've done:
- Created a new Azure Function App from the Azure Portal
- Turned on the "App Service Authentication" setting and instructed it to sign in with AAD (management mode is Express).
- Configured the app to have delegated permissions like "Sign in and read user profile" for Microsoft Graph.
- Created a new JavaScript function HttpTriggerJS1
- Changed the authorization level of this function to "Anonymous" (otherwise by default the "Function" level would not even allow me to run the function, always returning 401 Unauthorized)
- Installed the necessary Node module (
npm install request
)
And the actual function:
var request = require('request');
module.exports = function (context, req) {
var token = req.headers['x-ms-token-aad-access-token'];
var reqUrl = 'https://graph.microsoft.com/v1.0/me/';
request.get(reqUrl, {'auth': {'bearer': token}}, function (err, response, msg) {
context.res = {
body: msg
};
context.done();
});
};
Tested this function in a separate browser window. Signed me in to AAD correctly.
But the message returned from Graph was:
"{
"error": {
"code": "InvalidAuthenticationToken",
"message": "CompactToken parsing failed with error code: -2147184105",
"innerError": {
"request-id": "4c78551d-f0fe-4104-b1d3-e2d96fd3c02c",
"date": "2017-05-16T19:11:14"
}
}
}"
I looked into the token I got from req.headers['x-ms-token-aad-access-token']
. It's something like "AQABAA....", which seems different from the regular access_token I've seen before that starts with "eyJ....".
What could be wrong here? When calling the Graph API, am I supposed to be using the access_token from the request headers?
Thanks!
Edit:
According to Chris Gillum's suggestion, I also looked into the "on-behalf-of" flow. And here is my updated function, which acquires an access_token for a particular resource (https://graph.microsoft.com in my case) by providing the id_token (retrieved from the request headers).:
var request = require('request');
module.exports = function (context, req) {
var parameters = {
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
client_id: process.env.WEBSITE_AUTH_CLIENT_ID,
client_secret: process.env.WEBSITE_AUTH_CLIENT_SECRET,
assertion: req.headers['x-ms-token-aad-id-token'],
resource: 'https://graph.microsoft.com',
requested_token_use: 'on_behalf_of'
};
request.post('https://login.microsoftonline.com/microsoft.com/oauth2/token', {form: parameters}, function (aadErr, aadResponse, aadMsg) {
var msgJson = JSON.parse(aadMsg);
request.get('https://graph.microsoft.com/v1.0/me/', {'auth': {'bearer': msgJson.access_token}}, function (err, response, msg) {
context.res = {
body: msg
};
context.done();
});
});
};
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…