当我在 WebCredentials 中的呼叫中指定用户名和密码时,对EWS的呼叫工作正常。如果将 ExchangeService.UseDefaultCredentials 属性设置为True,则会收到401未经授权错误。
我不知道这是否重要,但是我们的Exchange管理员告诉我我正在混合环境中工作。我们同时运行Exchange Online和Exchange 2010(我认为应该是2013)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;
using System.Security.Cryptography.X509Certificates;
using System.Net;
namespace EWSLib
{
class Program
{
static ExchangeService _service;
static void Main(string[] args)
{
string defaultEmail = System.DirectoryServices.AccountManagement.UserPrincipal.Current.EmailAddress;
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
try
{
_service = new ExchangeService();
Appointment meeting = new Appointment(_service);
//-----------------------------------------------
// If I comment out
// "_service.UseDefaultCredentials = true"
// and uncomment the line "_service.Credentials = new WebCredentials("user@company.com", "password")"
// Then Everything works fine.
//------------------------------------------------
_service.UseDefaultCredentials = true;
//_service.Credentials = new WebCredentials("user@company.com", "password");
_service.TraceEnabled = true;
_service.TraceFlags = TraceFlags.All;
//_service.AutodiscoverUrl(defaultEmail, RedirectionUrlValidationCallback);
_service.Url = new Uri("https://example.com/EWS/Exchange.asmx");
// TEST MEETING
meeting.Subject = "The subject";
meeting.Body = "The boddy";
meeting.Start = DateTime.UtcNow.AddDays(5);
meeting.End = DateTime.UtcNow.AddDays(5).AddHours(1);
meeting.Location = "Someplace";
meeting.IsReminderSet = true;
meeting.RequiredAttendees.Add(defaultEmail);
meeting.ReminderMinutesBeforeStart = 60;
// Delegation
meeting.Save(new FolderId(WellKnownFolderName.Calendar, "delegator@company.com"), SendInvitationsMode.SendToAllAndSaveCopy);
// Verify that the meeting was created.
Item item = Item.Bind(_service, meeting.Id, new PropertySet(ItemSchema.Subject));
}
catch (Exception e)
{
//System.Diagnostics.Debug.WriteLine(e);
Console.WriteLine(e);
}
Console.ReadLine();
}
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
private static bool CertificateValidationCallBack(
object sender,
System.Security.Cryptography.X509Certificates.X509Certificate certificate,
System.Security.Cryptography.X509Certificates.X509Chain chain,
System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
// If the certificate is a valid, signed certificate, return true.
if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
{
Console.WriteLine("Valid Signed Certificate");
return true;
}
// If there are errors in the certificate chain, look at each error to determine the cause.
if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
{
if (chain != null && chain.ChainStatus != null)
{
foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
{
if ((certificate.Subject == certificate.Issuer) &&
(status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
{
// Self-signed certificates with an untrusted root are valid.
Console.WriteLine("Self-signed certificates with an untrusted root are valid.");
continue;
}
else
{
if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
{
// If there are any other errors in the certificate chain, the certificate is invalid,
// so the method returns false.
Console.WriteLine("there are any other errors in the certificate chain");
return false;
}
}
}
}
// When processing reaches this line, the only errors in the certificate chain are
// untrusted root errors for self-signed certificates. These certificates are valid
// for default Exchange server installations, so return true.
Console.WriteLine("Valid for some reason");
return true;
}
else
{
// In all other cases, return false.
Console.WriteLine("there are any other errors in the certificate chain");
return false;
}
}
}
}
答案 0 :(得分:1)
如果您的邮箱位于Office365上,那么我建议您改用Oauth。由于明年EWS https://blogs.technet.microsoft.com/exchange/2018/07/03/upcoming-changes-to-exchange-web-services-ews-api-for-office-365/的基本身份验证将不复存在。
如果您使用oAuth,则可以将Windows集成的Auth与ADAL库https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/wiki/AcquireTokenSilentAsync-using-Integrated-authentication-on-Windows-(Kerberos)结合使用,以利用当前登录的用户的优势。
答案 1 :(得分:0)
我们的用户帐户位于Exchange Online上。这就是为什么将 UseDefaultCredentials 设置为 True 无效的原因。
如果用户的邮箱作为Office 365的一部分托管在Exchange Online或Exchange Online中,则不能使用已登录用户的默认凭据。相反,请使用Credentials属性设置用户的凭据。对于Exchange Online,用户的凭据必须采用用户主体名称(UPN)形式。