【问题标题】:Unable to access Office 365 using NodeJS/node-outlook无法使用 NodeJS/node-outlook 访问 Office 365
【发布时间】:2015-07-01 02:07:37
【问题描述】:

我正在尝试创建一个 NodeJS 守护程序/服务应用程序,以使用 node-outlook 库访问 Office 365 邮件/联系人。 我能够创建 Office 365 试用订阅并注册我的应用程序。所以现在我可以访问我的应用程序的端点 URL、客户端 ID 和客户端密码。 这是我的代码:

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;
}

结果如下:

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

我已经尝试了 PEM 格式的不同证书,其“ca”属性为“credentials”。错误是一样的。

首先,我可以使用自行颁发的 PKI 证书吗? PKI 证书有哪些要求才能与 Azure AD 一起使用?我使用 SHA1 算法和 2048 位加密。这些够了吗?

这是我用作手册的内容: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

我还查看了 simple-oauth2 库的源代码,发现“ca”是唯一可以用于 PKI 设置的选项。它被明确检查。所有其他与 PKI 相关的 nodejs https 选项(证书、密钥、密码,...)都被忽略,永远不会得到实际的请求代码。

我是唯一遇到问题的人吗?

【问题讨论】:

    标签: node.js office365 azure-active-directory outlook-restapi


    【解决方案1】:

    错误是因为在身份验证请求中使用了机密而不是证书。在您的情况下,您根本不想使用秘密。听起来真正的问题是simple-oauth2 库是否会处理将身份验证请求转换为 Azure 期望的格式。格式的血腥细节在这里:Office 365 Rest API - Daemon week authentication

    我查看了simple-oauth2 的自述文件,他们的客户端凭据流示例使用秘密而不是基于证书的断言。查看配置代码,我看不到在那里执行任何基于证书的身份验证的能力,因此该库可能不适用于这种情况(除非我错过了它)。

    更新:好消息是adal-node library 确实支持使用证书,而且相当容易使用。棘手的部分是解决证书问题。

    我已经启动了一个示例 Node.js 脚本,您可以在此处找到它:https://github.com/jasonjoh/node-service。到目前为止,它只使用来自 Azure 的证书检索令牌。自述文件包含我整理证书所经历的所有步骤。

    【讨论】:

    • 感谢您的及时回复,杰森。这将是一个定期在云(不是 Azure)中运行的集成脚本。它应该与我们的系统同步 Office 365 数据。因此,如果我理解正确,应用程序类型是守护程序/服务。没有网络组件。您确定不需要 clientSecret 吗? Azure AD 将它连同 clientID 和访问端点一起发给了我。
    • 有没有办法使用clientSecret代替证书。 Azure AD 在逻辑上无论如何都在创建安全通道,如果我已经拥有 clientID、clientSecret 和唯一端点,为什么我还需要一些额外的证书来标识自己?
    • 不,当您使用应用程序权限/客户端凭据流时,Exchange 需要证书声明。这是为了防止有人获取您的客户端 ID 和机密并获得对所有同意您的应用程序的组织的全局访问权限的情况。您可以为此使用自签名证书。我会看看我是否能想出一个示例脚本。
    • 我刚刚用我正在处理的示例的链接更新了我的答案。希望这将有助于获取代币。
    • 再次感谢杰森。你很有帮助。我设法使用 node-outlook、jws 和 simple-oath2 库使其工作。我绝对希望在 Microsoft 官方文档中看到您的方法。
    猜你喜欢
    • 1970-01-01
    • 2020-11-18
    • 2016-09-24
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2017-09-14
    相关资源
    最近更新 更多