Reputation: 51
I am trying to create an app that runs from an AWS lambda that acts as a middle man for customers wanting to sign up for a booking using Microsoft Bookings. Following the documentation I am able to generate an access token for Graph, but I get an authorization denial when I try to request information from bookings through the api.
My Code:
import request from "request";
import { Callback } from "./callback";
const APP_ID = process.env.BOOKINGS_APP_ID;
const APP_SECRET = process.env.BOOKINGS_API_SECRET;
const TOKEN_ENDPOINT = `https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token`;
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "client_credentials",
resource: "https://graph.microsoft.com",
scope: "https://graph.microsoft.com/.default",
};
export default class Bookings {
public static async listBusinesses(callback: Callback) {
Bookings.generateAPIToken((err: string | null, data: any) => {
const options = {
// body: {},
headers: {
"Authorization": `Bearer ${data}`,
"Content-Type": "application/json",
},
method: "GET",
url: "https://graph.microsoft.com/beta/bookingBusinesses",
};
console.log(data);
return request(options, (error: string, res: any) => {
if (error) {
return callback(error, {});
}
return callback(null, JSON.parse(res.body));
});
});
}
public static async generateAPIToken(callback: Callback) {
request.post({ url: TOKEN_ENDPOINT, form: requestParams }, (err, res, body) => {
if (err) {
return callback(err, {});
}
return callback(null, JSON.parse(body).access_token);
});
}
}
The error that I get:
{
error: {
code: '',
message: 'Authorization has been denied for this request.',
innerError: {
'request-id': '695d3f90-357d-490c-b980-4a2018dd39a5',
date: '2020-06-08T03:21:59'
}
}
}
I have also tried using the microsoft-graph-client library to access bookings but that doesn't work either. What I am doing wrong? Thank you for any help.
Upvotes: 0
Views: 1871
Reputation: 15754
We can see the document shows the graph api(bookingBusinesses) which you want to request requires delegated type permissions and not support application type permission.
So we can not use "client_credentials" grant flow, your code shows you use "client_credentials" as the grant type. You can use "username/password" grant flow to get the access token instead. So the param you request for the access token should be like below:
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
scope: "https://graph.microsoft.com/.default",
username: "your user name/email(like [email protected])",
password: "your password"
};
By the way, I noticed the "TOKEN_ENDPOINT" in your code is https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token
and you use both params resource
and scope
in requestParams
. If we use v1 endpoint as your code, we just need to use the param resource
. If we use v2 endpoint(https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/token
), we need to use use the param scope
instead of the param resource
. The code I provided above use v2, so I use scope
param and you also need to change the "TOKEN_ENDPOINT" to v2(just add a v2.0
between the oauth2/
and /token
).
If you don't want to change the "TOKEN_ENDPOINT" to v2, just use the params like below:
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
resource: "https://graph.microsoft.com",
username: "your user name/email(like [email protected])",
password: "your password"
};
Hope it helps~
Upvotes: 4