EWS GetUserPhoto 委派给仅应用程序身份验证
EWS GetUserPhoto Delegated to App-Only Authentication
我目前正在使用委托授权获取用户照片,如下所示:
var pcaOptions = new PublicClientApplicationOptions
{
ClientId = "ClientID",
TenantId = "TenantId"
};
var pca = PublicClientApplicationBuilder.CreateWithApplicationOptions(pcaOptions).Build();
var ewsScopes = new string[] { "https://outlook.office365.com/EWS.AccessAsUser.All" };
var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();
string email = "SomeEmail@email.com";
HttpWebRequest request = WebRequest.Create(string.Format("https://outlook.office365.com/EWS/Exchange.asmx/s/GetUserPhoto?email={0}&size=HR648x648", email)) as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
我正在尝试更改为使用仅应用程序身份验证。我设法获得了访问令牌,但似乎无法像委托授权那样完成。
以下是我切换到使用仅应用程序身份验证所做的操作。
var cca = ConfidentialClientApplicationBuilder
.Create("ClientID")
.WithClientSecret("ClientSecret")
.WithTenantId("TenantID")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
string email = "SomeEmail@email.com";
HttpWebRequest request = WebRequest.Create(string.Format("https://outlook.office365.com/EWS/Exchange.asmx/s/GetUserPhoto?email={0}&size=HR648x648", email)) as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
//Error: The remote server returned an error: (400) Bad Request.
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
错误:远程服务器返回错误:(400) 错误请求。
编辑:已更新为使用 SOAP 操作,如下所示,但我收到此错误:“远程服务器返回错误:(500) 内部服务器错误。”
有什么我可能遗漏的吗?
var cca = ConfidentialClientApplicationBuilder
.Create("ClientID")
.WithClientSecret("ClientSecret")
.WithTenantId("TenantID")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
HttpWebRequest request = WebRequest.Create("https://outlook.office365.com/EWS/Exchange.asmx") as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
request.Method = "POST";
XmlDocument SOAPReqBody = new XmlDocument();
SOAPReqBody.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:t=""https://schemas.microsoft.com/exchange/services/2006/types"" xmlns:m=""https://schemas.microsoft.com/exchange/services/2006/messages"">
<soap:Header>
<t:RequestServerVersion Version=""Exchange2013""/>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>impersonatedUser@mail.com</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<m:GetUserPhoto>
<m:Email>UserEmail@mail.com</m:Email>
<m:SizeRequested>HR648x648</m:SizeRequested>
</m:GetUserPhoto>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SOAPReqBody.Save(stream);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
//The remote server returned an error: (500) Internal Server Error.
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
EWS 中的应用程序令牌要求您模拟已知用户(当您请求然后采用该身份),因此您需要使用 SOAP 操作 https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getuserphoto-operation 然后模拟真实用户(如果你有应用程序策略,你需要小心,否则租户中的任何用户都应该工作)例如
var cca = ConfidentialClientApplicationBuilder
.Create("d4")
.WithClientSecret("s")
.WithTenantId("x")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = cca.AcquireTokenForClient(ewsScopes).ExecuteAsync().Result;
HttpWebRequest request = WebRequest.Create("https://outlook.office365.com/EWS/Exchange.asmx") as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
request.Method = "POST";
XmlDocument SOAPReqBody = new XmlDocument();
SOAPReqBody.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:m=""http://schemas.microsoft.com/exchange/services/2006/messages"" xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Header>
<t:RequestServerVersion Version=""Exchange2016"" />
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:SmtpAddress>user@domain.com</t:SmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<m:GetUserPhoto>
<m:Email>user@domain.com</m:Email>
<m:SizeRequested>HR48x48</m:SizeRequested>
</m:GetUserPhoto>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SOAPReqBody.Save(stream);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//The remote server returned an error: (500) Internal Server Error.
Stream stream = response.GetResponseStream();
XmlDocument Response = new XmlDocument();
Response.Load(stream);
var PictureDataNodes = Response.GetElementsByTagName("PictureData");
Byte[] PictureData = Convert.FromBase64String(PictureDataNodes[0].InnerText);
File.WriteAllBytes("c:\temp\pictest.jpg", PictureData);
}
}
我目前正在使用委托授权获取用户照片,如下所示:
var pcaOptions = new PublicClientApplicationOptions
{
ClientId = "ClientID",
TenantId = "TenantId"
};
var pca = PublicClientApplicationBuilder.CreateWithApplicationOptions(pcaOptions).Build();
var ewsScopes = new string[] { "https://outlook.office365.com/EWS.AccessAsUser.All" };
var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();
string email = "SomeEmail@email.com";
HttpWebRequest request = WebRequest.Create(string.Format("https://outlook.office365.com/EWS/Exchange.asmx/s/GetUserPhoto?email={0}&size=HR648x648", email)) as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
我正在尝试更改为使用仅应用程序身份验证。我设法获得了访问令牌,但似乎无法像委托授权那样完成。
以下是我切换到使用仅应用程序身份验证所做的操作。
var cca = ConfidentialClientApplicationBuilder
.Create("ClientID")
.WithClientSecret("ClientSecret")
.WithTenantId("TenantID")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
string email = "SomeEmail@email.com";
HttpWebRequest request = WebRequest.Create(string.Format("https://outlook.office365.com/EWS/Exchange.asmx/s/GetUserPhoto?email={0}&size=HR648x648", email)) as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
//Error: The remote server returned an error: (400) Bad Request.
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
错误:远程服务器返回错误:(400) 错误请求。
编辑:已更新为使用 SOAP 操作,如下所示,但我收到此错误:“远程服务器返回错误:(500) 内部服务器错误。”
有什么我可能遗漏的吗?
var cca = ConfidentialClientApplicationBuilder
.Create("ClientID")
.WithClientSecret("ClientSecret")
.WithTenantId("TenantID")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
HttpWebRequest request = WebRequest.Create("https://outlook.office365.com/EWS/Exchange.asmx") as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
request.Method = "POST";
XmlDocument SOAPReqBody = new XmlDocument();
SOAPReqBody.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8"" ?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:t=""https://schemas.microsoft.com/exchange/services/2006/types"" xmlns:m=""https://schemas.microsoft.com/exchange/services/2006/messages"">
<soap:Header>
<t:RequestServerVersion Version=""Exchange2013""/>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>impersonatedUser@mail.com</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<m:GetUserPhoto>
<m:Email>UserEmail@mail.com</m:Email>
<m:SizeRequested>HR648x648</m:SizeRequested>
</m:GetUserPhoto>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SOAPReqBody.Save(stream);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse){
//The remote server returned an error: (500) Internal Server Error.
Stream stream = response.GetResponseStream();
using (MemoryStream ms = new MemoryStream())
{
string encodedPhoto = Convert.ToBase64String((ms.ToArray()));
}
}
EWS 中的应用程序令牌要求您模拟已知用户(当您请求然后采用该身份),因此您需要使用 SOAP 操作 https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/getuserphoto-operation 然后模拟真实用户(如果你有应用程序策略,你需要小心,否则租户中的任何用户都应该工作)例如
var cca = ConfidentialClientApplicationBuilder
.Create("d4")
.WithClientSecret("s")
.WithTenantId("x")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
var authResult = cca.AcquireTokenForClient(ewsScopes).ExecuteAsync().Result;
HttpWebRequest request = WebRequest.Create("https://outlook.office365.com/EWS/Exchange.asmx") as HttpWebRequest;
request.Headers.Add("Authorization", "Bearer " + authResult.AccessToken);
request.Method = "POST";
XmlDocument SOAPReqBody = new XmlDocument();
SOAPReqBody.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:m=""http://schemas.microsoft.com/exchange/services/2006/messages"" xmlns:t=""http://schemas.microsoft.com/exchange/services/2006/types"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Header>
<t:RequestServerVersion Version=""Exchange2016"" />
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:SmtpAddress>user@domain.com</t:SmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<m:GetUserPhoto>
<m:Email>user@domain.com</m:Email>
<m:SizeRequested>HR48x48</m:SizeRequested>
</m:GetUserPhoto>
</soap:Body>
</soap:Envelope>");
using (Stream stream = request.GetRequestStream())
{
SOAPReqBody.Save(stream);
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
//The remote server returned an error: (500) Internal Server Error.
Stream stream = response.GetResponseStream();
XmlDocument Response = new XmlDocument();
Response.Load(stream);
var PictureDataNodes = Response.GetElementsByTagName("PictureData");
Byte[] PictureData = Convert.FromBase64String(PictureDataNodes[0].InnerText);
File.WriteAllBytes("c:\temp\pictest.jpg", PictureData);
}
}