使用带有x509证书的SOAP上的Nodejs验证Microsoft EWS

时间:2017-05-02 17:56:23

标签: node.js azure soap exchangewebservices x509certificate

我使用Microsoft Graph API在Azure Active Directory中访问用户等方面取得了巨大成功,但是仍需要EWS和SOAP的两件事情是检索用户照片并将邮件规则添加到用户邮件帐户。 我为所有内容使用服务帐户,并模拟帐户管理员提出请求。

尝试使用与Graph API相同的访问令牌后,收到错误消息: The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2

阅读,我明白,因为EWS需要对帐户拥有完全权限,所以您不能只是传递访问令牌,但您还必须做某事"使用x509证书。

在我注册的应用程序中,在Azure中,我已调整清单,以便包含自签名证书,以便我拥有:

 "keyCredentials": [{
  "customKeyIdentifier": "lhbl...../w0bjA6l1mQ8=",
  "keyId": "774D2C35-2D58-.....-AC34B15472BA",
  "type": "AsymmetricX509Cert",
  "usage": "Verify",
  "value": "MIIFtTCCA52gAwIB.....mmgufQ2rW5GSjEEXOlO1c7qw=="
}],

我的理解是customKeyIdentifier是密钥的Base64,来自命令:echo $(openssl x509 -in cert.pem -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64

value确实是关键内容,删除了-----BEGIN CERTIFICATE----------END CERTIFICATE-----,并删除了所有新行(否则在清单中,json不是有效的)。

keyId是我刚刚使用uuidgen命令在终端上生成的GUID,我不会以任何方式直接认为与证书直接相关

我当时不确定的是,我必须在我的代码中进行更改,即尝试对EWS进行身份验证。

我开始使用node-ews库,我的配置如下:

var ewsConfig = {
username: userEmail,
token: self.accessToken,
host: 'https://outlook.office365.com/EWS/Exchange.asmx',
auth: 'bearer'
};
var ews = new EWS(ewsConfig);
var ewsFunction = 'UpdateInboxRules';
ews.run(ewsFunction, ewsArgs)
  .then(result => {
    cb(null, result)
  })
  .catch(err => {
    cb(err);
  });
};

self.accessToken与访问Microsoft Graph API时收到的标记相同。

所以,总之,我的问题是:

  1. 我需要对我的请求做什么才能告诉服务器同时验证x509证书,我读到我可能还需要将它转换为PKCS12证书吗?
  2. 我可以使用与我成功使用相同的accessToken来访问图形api吗?
  3. Nodejs在任何地方都有代码片段吗?
  4. keyId可以成为我想要的任何标识符吗?
  5. 我回复的回复包含:

    { 'content-length': '0',
            server: 'Microsoft-IIS/8.5',
            'request-id': '9b0d7a1b-85e6-40f6-9af0-7f65fc6669dc',
            'x-calculatedfetarget': 'MM1P123CU001.internal.outlook.com',
            'x-backendhttpstatus': '401, 401',
            'set-cookie': [Object],
            'x-feproxyinfo': 'MM1P123CA0026.GBRP123.PROD.OUTLOOK.COM',
            'x-calculatedbetarget': 'MM1P123MB1337.GBRP123.PROD.OUTLOOK.COM',
            'x-ms-diagnostics': '2000001;reason="The access token is acquired using an authentication method that is too weak to allow access for this application. Presented auth strength was 1, required is 2.";error_category="invalid_token"',
            'x-diaginfo': 'MM1P123MB1337',
            'x-beserver': 'MM1P123MB1337',
            'x-feserver': 'MM1P123CA0026, VI1PR0701CA0059',
            'x-powered-by': 'ASP.NET',
            'www-authenticate': 'Bearer client_id="00000002-0000-0ff1-ce00-000000000000", trusted_issuers="00000001-0000-0000-c000-000000000000@*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.windows.net/common/oauth2/authorize", error="invalid_token",Basic Realm="",Basic Realm="",Basic Realm=""',
            date: 'Tue, 02 May 2017 18:08:54 GMT',
            connection: 'close' } }
    

    谢谢,非常感谢

1 个答案:

答案 0 :(得分:0)

我按照这篇文章来生成access_token https://blogs.msdn.microsoft.com/arsen/2015/09/18/certificate-based-auth-with-azure-service-principals-from-linux-command-line/,确实遇到了jwt签名的问题,我不得不使用openssl rsa -check -in key.pem来解密密钥并将其保存在文本文件中。然后jwt签约工作。您还需要模仿,请参阅此https://github.com/CumberlandGroup/node-ews/issues/39

它可能对node-ews有所帮助。我没有用node-ews测试这个场景。如果您有兴趣通过ews托管api编写代码来查看更强大的方法,我已将ews-managed-api的c#版本移植到ews-javascript-api,以下是与ews-javascript-api实现相同的示例代码,测试并确认工作代码。

var ews = require("ews-javascript-api");
ews.EwsLogging.DebugLogEnabled = false;
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.OAuthCredentials("oauth access_token");
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx");
exch.ImpersonatedUserId = new 
ews.ImpersonatedUserId(ews.ConnectingIdType.SmtpAddress, "user@domain.com");
exch.HttpHeaders = { "X-AnchorMailbox": "user@domain.com" };
var rule = new ews.Rule();
rule.DisplayName = "MoveInterestingToJunk";
rule.Priority = 1;
rule.IsEnabled = true;
rule.Conditions.ContainsSubjectStrings.Add("Interesting");
rule.Actions.MoveToFolder = new ews.FolderId(ews.WellKnownFolderName.JunkEmail);
var ruleop = new ews.CreateRuleOperation(rule);
exch.UpdateInboxRules([ruleop], true)
    .then(function (response) {
    console.log("success - update-inboxrules");
    ews.EwsLogging.Log(response, true, true);
}, function (err) {
    debugger;
    console.log("error in update-inboxrules");
    ews.EwsLogging.Log(err, true, true);
});