我使用 Microsoft Graph API 访问 Azure Active Directory 中的用户等取得了巨大成功,但是仍然需要 EWS 和 SOAP 的两件事是检索用户照片并向用户邮件帐户添加邮件规则。 我使用服务帐户来处理所有事情,并冒充帐户管理员来提出请求。
尝试使用与 Graph API 相同的访问 token 后,我收到错误:
访问 token 是使用身份验证方法获取的,该身份验证方法太弱,无法允许此应用程序访问。提供的身份验证强度为 1,所需的身份验证强度为 2
。
通过阅读,我了解到,由于 EWS 需要对帐户的完全权限,因此您不能只传递访问 token ,还必须使用 x509 证书“执行某些操作”。
在我注册的应用程序中,在 Azure 中,我调整了 list 以包含自签名证书,这样我就可以:
"keyCredentials": [{
"customKeyIdentifier": "lhbl...../w0bjA6l1mQ8=",
"keyId": "774D2C35-2D58-.....-AC34B15472BA",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "MIIFtTCCA52gAwIB.....mmgufQ2rW5GSjEEXOlO1c7qw=="
}],
我的理解是 customKeyIdentifier
是 key 的 Base64,来自命令:echo $(openssl x509 -in cert.pem -fingerprint -noout) | sed 's/SHA1 指纹=//g' | sed 's/://g' | xxd -r -ps | xxd -r -ps | Base64
值
实际上是关键内容,包含-----BEGIN CERTIFICATE-----
和-----END CERTIFICATE -----
已删除,所有新行也已删除(否则在 list 中,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 时收到的 token 相同。
所以,总而言之,我的问题是:
- 我需要对我的请求执行什么操作,以便告诉服务器也对 x509 证书进行身份验证,我了解到我可能还需要将其转换为 PKCS12 证书?
- 我可以使用与我成功访问图形 API 相同的 accessToken 吗?
- 是否有 Nodejs 执行此操作的代码片段?
keyId
可以是我想要提供的任何标识符吗?
我收到的回复包含:
{ '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' } }
谢谢,非常感谢
最佳答案
我按照这篇文章生成了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 来解密 key 并将其保存在文本文件中。然后 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, "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="186d6b7d6a587c7775797176367b7775" rel="noreferrer noopener nofollow">[email protected]</a>");
exch.HttpHeaders = { "X-AnchorMailbox": "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="cdb8bea8bf8da9a2a0aca4a3e3aea2a0" rel="noreferrer noopener nofollow">[email protected]</a>" };
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);
});
关于node.js - 使用 Nodejs over SOAP 和 x509 证书对 Microsoft EWS 进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43744302/