上周我在这里提出了一个关于EWS的问题,我收到了错误消息:
401:未经授权 - 访问令牌无效
我设法通过使用X.509证书而不是客户端凭据(来自AAD的客户端ID和客户端密钥)来解决此错误。现在,通过使用证书,我收到一条新的错误消息:
403:禁止 - 范围不够
我认为这与AAD中的权限有关吗?
我的权限如下(只有一个权限):
应用程序权限:从所有邮箱中读取和写入电子邮件
我如何收到访问令牌:
//Create the certificate file, using the path (certFile), password (certPassword) and the MachineKeySet
X509Certificate2 cert = new X509Certificate2(certFile, certPassword, X509KeyStorageFlags.MachineKeySet);
//Create the ClientAssertionCertificate using the clientID and the actual certificate
ClientAssertionCertificate cac = new ClientAssertionCertificate(clientID, cert);
//Retreive the access token using the serverName and client assertion
authenticationResult = authenticationContext.AcquireToken(serverName, cac);
//authenticationResult = authenticationContext.AcquireToken(serverName, cc);
ExchangeService exchange = new ExchangeService(ExchangeVersion.Exchange2013);
exchange.Url = new Uri(serverName + "ews/exchange.asmx");
exchange.TraceEnabled = true;
exchange.TraceFlags = TraceFlags.All;
exchange.Credentials = new OAuthCredentials(authenticationResult.AccessToken);
如此调用FindItems
方法:
ItemView view = new ItemView(5);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
var tempId = id.Replace('-', '/').Replace('_', '+');
SearchFilter.IsEqualTo searchid = new SearchFilter.IsEqualTo(ItemSchema.Id, tempId);
// This results in a FindItem call to EWS.
FindItemsResults<Microsoft.Exchange.WebServices.Data.Item> results = exchange.FindItems(WellKnownFolderName.Inbox, searchid, view);
出现错误。
有人可以解释可能导致此类错误的原因吗?
答案 0 :(得分:1)
只有Office 365 REST API支持细粒度访问,例如“从所有邮箱中读取和写入电子邮件”。对于EWS,您需要“使用对所有邮箱具有完全访问权限的Exchange Web服务”权限。如果您在查找此权限时遇到问题,请告诉我们。
答案 1 :(得分:0)
OAuth流程不承担X509Certificate2身份验证。您应该在AAD中注册多租户应用程序(Exchange Online可用)。当您通过OAuth进行身份验证时,需要3个以下代理权限才能访问邮箱:
要授予对您的应用程序的访问权限,应将用户重定向到https://login.microsoftonline.com/common/oauth2/authorize(带有相应的参数)。授予权限后,您将收到带有授权代码的响应,该代码应交换为访问/刷新令牌:
ClientCredential credential = new ClientCredential(clientId, appKey);
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/common", false);
var url = new Uri(Request.Url.GetLeftPart(UriPartial.Path));
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
code, url, credential, "https://outlook.office365.com/");
其中 clientId 和 appKey - 已注册应用的参数代码 - 是从OAuth响应中收到的授权码。