I am trying to create a NodeJS daemon/service application for accessing Office 365 mail/contacts using node-outlook library. I was able to create an Office 365 trial subscription and register my application. So now I have access endpoint URL, Client ID and Client Secret for my app. Here is my code:
var outlook = require("node-outlook");
var token;
process.env.DEBUG = true;
var fs = require('fs');
var credentials = {
clientID: "<id>",
clientSecret: "<secret>",
site: "https://login.microsoftonline.com/<my-tenant-id>",
authorizationPath: "/oauth2/authorize",
tokenPath: "/oauth2/token",
useBasicAuthorizationHeader: false,
rejectUnauthorized: false,
ca: fs.readFileSync('pki/some.pem', { encoding: 'ascii' }),
};
var oauth2 = require('simple-oauth2')(credentials);
oauth2.client.getToken({}, saveToken);
function saveToken(error, result) {
if (error) {
console.log('Access Token Error: ', error);
return;
}
token = oauth2.accessToken.create(result);
var outlookClient = new outlook.Microsoft.OutlookServices.Client(
'https://outlook.office365.com/api/v1.0',
getAccessToken);
outlookClient.me.folders.getFolder('Inbox').messages.getMessages().fetchAll(10).then(
function (result) {
console.log('Success: ', result);
},
function (error) {
console.log('Error: ', error);
console.log('Headers: ', error.getAllResponseHeaders());
});
}
function getAccessToken() {
var deferred = new outlook.Microsoft.Utility.Deferred();
if (token.expired()) {
token.refresh(function (error, result) {
if (error) {
console.log("Refresh token error: ", error.message);
}
token = result;
deferred.resolve(token.token.access_token);
});
}
else {
deferred.resolve(token.token.access_token);
}
return deferred;
}
And this is the result:
Error: { UNSENT: 0,
OPENED: 1,
HEADERS_RECEIVED: 2,
LOADING: 3,
DONE: 4,
readyState: 4,
onreadystatechange: [Function],
responseText: '',
responseXML: '',
status: 401,
statusText: null,
open: [Function],
setDisableHeaderCheck: [Function],
setRequestHeader: [Function],
getResponseHeader: [Function],
getAllResponseHeaders: [Function],
getRequestHeader: [Function],
send: [Function],
handleError: [Function],
abort: [Function],
addEventListener: [Function],
removeEventListener: [Function],
dispatchEvent: [Function] }
Headers: content-length: 0
server: Microsoft-IIS/8.0
request-id: 07931460-4fbf-4028-bc7b-fe350c240a1b
x-calculatedbetarget: BLUPR10MB0594.namprd10.prod.outlook.com
x-backendhttpstatus: 401
x-ms-diagnostics: 2000010;reason="The access token is acquired using an authenti
cation method that is too weak to allow access for this application. Presented a
uth strength was 1, required is 2.";error_category="insufficient_auth_strength"
x-diaginfo: BLUPR10MB0594
x-beserver: BLUPR10MB0594
x-powered-by: ASP.NET
x-feserver: CY1PR01CA0008
www-authenticate: Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trust
ed_issuers="00000001-0000-0000-c000-000000000000@*", token_types="app_asserted_u
ser_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize",
error="invalid_token",Basic Realm="",Basic Realm=""
date: Mon, 29 Jun 2015 18:34:32 GMT
connection: close
I already tried different certificates in PEM format with "ca" attribute of "credentials". The error is the same.
So first of all, can I use self-issued PKI certificates? What are the requirements for the PKI certificates so they would work with Azure AD? I use SHA1 algorithm and 2048-bit encryption. Is it enough of those?
This is what I used as a manual: http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
Also I looked at the source code of simple-oauth2 library and found that "ca" is the only option the one can use for the PKI settings. It is explicitly checked. All the other PKI related nodejs https options (cert,key,passphrase,...) are just ignored and never get to the actual request code.
Am I the only one who ran into the problem?