EWS api - 无法连接本地 ExchangeServer
EWS api - Unable to connect ExchangeServer on-prem
我正在实施 Microsoft EWS api 以便从本地 Exchange 服务器获取电子邮件。考虑到微软已经放弃开发,我使用的是ews api的sherlock1982 fork。我的应用程序是用 .net core 2.1 编写的,当 运行 在我的本地 PC (win10) 上时,一切正常。 考虑到它是 Linux,它无法自动获取自动发现 url,因此我在代码中手动设置它,如 github 页面上的建议。
public async void GetInbox()
{
string ewsUrl = "https://mail.domain.com/EWS/Exchange.asmx";
try
{
var service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.UseDefaultCredentials = false;
// service.Credentials = new NetworkCredential("domainUsername", "password", "domain");
service.Url = new Uri(ewsUrl);
Mailbox mb = new Mailbox("emailAddress");
var cache = new System.Net.CredentialCache();
cache.Add(service.Url, "NTLM", new
System.Net.NetworkCredential("domainUsername", "password",
"domain"));
service.Credentials = cache;
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
Folder inbox = await Folder.Bind(service, fid);
if (inbox != null)
{
_database.LogEvent("LOG", "GetInbox", $"InboxCount: {inbox.TotalCount}");
}
}
catch (Exception e)
{
_database.LogEvent("Error", "GetInbox", $"{e.Message}");
}
}
当部署到测试服务器 运行 CentOS7 时,我收到以下消息:
请求失败。无法建立 SSL 连接,请参阅内部异常。
at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.GetResponse(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\EwsHttpWebRequest.cs:line 147
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 798
--- End of inner exception stack trace ---
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 808
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 688
at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\SimpleServiceRequestBase.cs:line 57
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.ExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\MultiResponseServiceRequest.cs:line 134
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 325
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 345
at ExchangeFiles.Email.Download_PI_Files_Email() in D:\dev_in_progress\get_emails_v1\ExchangeFiles\Email.cs:line 199
我试过忽略证书
服务点管理器
.ServerCertificateValidationCallback +=
(发件人、证书、链、sslPolicyErrors) => true;
但运气不好(我遇到了同样的错误)。
更新:
我添加了以下代码
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
{
if (cert.GetCertHashString().ToLower() == "someHashCert")
{
return true;
}
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; //Is valid
}
return false;
}
在创建 HttpClientHandler 的代码中。它进入 if "cert.GetCertHashString().ToLower()" 内部,这很好。我从浏览器复制了 someHashCert 的值。
我也尝试设置
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
但是此代码(以及检查证书时上面的代码)的错误是:
请求失败。该处理程序不支持使用 libcurl (7.29.0) 及其 SSL 后端 ("NSS/3.44") 的这种组合来自定义处理证书。需要基于“OpenSSL/1.0.2k-fips”的 SSL 后端。考虑使用 System.Net.Http.SocketsHttpHandler.
如果我设置
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true);
我得到:
请求失败。 GSSAPI 操作因错误而失败 - 请求了不受支持的机制(未知错误)。
我也曾尝试为来自 MS 文档的证书设置回调 cert for ews api,但随后收到“无法获取本地颁发者证书”消息。
不确定这是前进还是后退...我感觉我已经尝试了一切...
更新2
ExchangeSever版本为2016,使用NTLM认证和TLS1.0/1.1
我试过 curl -v -k -i --anyauth -u : mail.server.domain:443 它说
* About to connect() to mail.server.domain: port 443 (#0)
* Trying xx.xx.xx.xxx...
* Connected to mail.server.domain (xx.xx.xx.xxx) port 443 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mail.server.domain::443
> Accept: */*
欢迎任何想法...谢谢
在 Cent OS 上更新您的 TLS。
CentOS 7.
上应该可以使用 TLSv1.2
Some documentation.
Linux OpenSSL 1.1.1 在不同 Linux OS.
中支持 TLS v1.3
RHEL 8 - Red Hat Enterprise Linux 8 是第一个将 TLS v1.3 协议完全集成到操作系统中的企业 Linux 发行版。
Older CentOS 和 RHEL OS 版本默认安装了 OpenSSL v1.0.2,因此本机不支持 TLS v1.3。
可以通过 yum 将 OpenSSL 更新到 OpenSSL v1.1.1 以支持 TLS v1.3。
Blockquote
如何在 CentOS RedHat Linux 上安装 OpenSSL v1.1.1:
使用 OpenSSL 版本命令验证 OpenSSL 版本:
openssl 版本
安装wget(如果没有安装):
yum 安装 wget
使用wget下载最新版本:
wget https://ftp.openssl.org/source/old/1.1.1/openssl-1.1.1.tar.gz
解压文件:
tar xvf openssl-1.1.1.tar.gz
需要进一步配置,请在进行任何更改之前咨询您的系统管理员。
默认情况下在系统范围内禁用。如果您在系统上启用 TLS v1.3 进行测试,则
OS 和 .net 框架应该支持 TLS。
检查OS,如果不支持TLS 1.2则升级
然后使用支持 TLS 1.2 /1.3 的 Right .net 框架
在 Cent OS 上也安装自签名证书。
.NET 是否支持 TLS 1.3?
对于 .NET,此时的官方指导(通过上面的最佳实践页面)是依靠底层 OS 来提供 TLS 版本(它将自动默认为最强的可用版本TLS 协议),并避免 hardcoding/specifying 在应用程序代码中使用明确的 TLS 版本。
Star配合 .NET Framework 4.7,默认配置是使用 OS TLS 版本。
其他可能有用的链接:https://github.com/dotnet/docs/issues/4675 and https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
不幸的是,这里的建议没有任何效果。
我在 github 上发现了一些关于类似问题的评论,以及如何将项目更新到 .NET core 3.1 来修复错误,所以我决定试一试...
这不是一项小工作,我在解决方案中有几个项目,但我可以确认,从 .NET core 2.1 更新到 .NET core 3.1 后,一切正常。
我正在实施 Microsoft EWS api 以便从本地 Exchange 服务器获取电子邮件。考虑到微软已经放弃开发,我使用的是ews api的sherlock1982 fork。我的应用程序是用 .net core 2.1 编写的,当 运行 在我的本地 PC (win10) 上时,一切正常。 考虑到它是 Linux,它无法自动获取自动发现 url,因此我在代码中手动设置它,如 github 页面上的建议。
public async void GetInbox()
{
string ewsUrl = "https://mail.domain.com/EWS/Exchange.asmx";
try
{
var service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.UseDefaultCredentials = false;
// service.Credentials = new NetworkCredential("domainUsername", "password", "domain");
service.Url = new Uri(ewsUrl);
Mailbox mb = new Mailbox("emailAddress");
var cache = new System.Net.CredentialCache();
cache.Add(service.Url, "NTLM", new
System.Net.NetworkCredential("domainUsername", "password",
"domain"));
service.Credentials = cache;
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
Folder inbox = await Folder.Bind(service, fid);
if (inbox != null)
{
_database.LogEvent("LOG", "GetInbox", $"InboxCount: {inbox.TotalCount}");
}
}
catch (Exception e)
{
_database.LogEvent("Error", "GetInbox", $"{e.Message}");
}
}
当部署到测试服务器 运行 CentOS7 时,我收到以下消息:
请求失败。无法建立 SSL 连接,请参阅内部异常。
at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.GetResponse(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\EwsHttpWebRequest.cs:line 147
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 798
--- End of inner exception stack trace ---
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 808
at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 688
at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\SimpleServiceRequestBase.cs:line 57
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.ExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\MultiResponseServiceRequest.cs:line 134
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 325
at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 345
at ExchangeFiles.Email.Download_PI_Files_Email() in D:\dev_in_progress\get_emails_v1\ExchangeFiles\Email.cs:line 199
我试过忽略证书 服务点管理器 .ServerCertificateValidationCallback += (发件人、证书、链、sslPolicyErrors) => true;
但运气不好(我遇到了同样的错误)。
更新: 我添加了以下代码
ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
{
if (cert.GetCertHashString().ToLower() == "someHashCert")
{
return true;
}
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true; //Is valid
}
return false;
}
在创建 HttpClientHandler 的代码中。它进入 if "cert.GetCertHashString().ToLower()" 内部,这很好。我从浏览器复制了 someHashCert 的值。 我也尝试设置
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
但是此代码(以及检查证书时上面的代码)的错误是: 请求失败。该处理程序不支持使用 libcurl (7.29.0) 及其 SSL 后端 ("NSS/3.44") 的这种组合来自定义处理证书。需要基于“OpenSSL/1.0.2k-fips”的 SSL 后端。考虑使用 System.Net.Http.SocketsHttpHandler.
如果我设置
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true);
我得到: 请求失败。 GSSAPI 操作因错误而失败 - 请求了不受支持的机制(未知错误)。
我也曾尝试为来自 MS 文档的证书设置回调 cert for ews api,但随后收到“无法获取本地颁发者证书”消息。
不确定这是前进还是后退...我感觉我已经尝试了一切...
更新2 ExchangeSever版本为2016,使用NTLM认证和TLS1.0/1.1
我试过 curl -v -k -i --anyauth -u : mail.server.domain:443 它说
* About to connect() to mail.server.domain: port 443 (#0)
* Trying xx.xx.xx.xxx...
* Connected to mail.server.domain (xx.xx.xx.xxx) port 443 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mail.server.domain::443
> Accept: */*
欢迎任何想法...谢谢
在 Cent OS 上更新您的 TLS。 CentOS 7.
上应该可以使用 TLSv1.2Some documentation.
Linux OpenSSL 1.1.1 在不同 Linux OS.
中支持 TLS v1.3RHEL 8 - Red Hat Enterprise Linux 8 是第一个将 TLS v1.3 协议完全集成到操作系统中的企业 Linux 发行版。
Older CentOS 和 RHEL OS 版本默认安装了 OpenSSL v1.0.2,因此本机不支持 TLS v1.3。 可以通过 yum 将 OpenSSL 更新到 OpenSSL v1.1.1 以支持 TLS v1.3。
Blockquote
如何在 CentOS RedHat Linux 上安装 OpenSSL v1.1.1: 使用 OpenSSL 版本命令验证 OpenSSL 版本:
openssl 版本
安装wget(如果没有安装):
yum 安装 wget
使用wget下载最新版本:
wget https://ftp.openssl.org/source/old/1.1.1/openssl-1.1.1.tar.gz
解压文件:
tar xvf openssl-1.1.1.tar.gz
需要进一步配置,请在进行任何更改之前咨询您的系统管理员。
默认情况下在系统范围内禁用。如果您在系统上启用 TLS v1.3 进行测试,则
OS 和 .net 框架应该支持 TLS。 检查OS,如果不支持TLS 1.2则升级 然后使用支持 TLS 1.2 /1.3 的 Right .net 框架 在 Cent OS 上也安装自签名证书。
.NET 是否支持 TLS 1.3?
对于 .NET,此时的官方指导(通过上面的最佳实践页面)是依靠底层 OS 来提供 TLS 版本(它将自动默认为最强的可用版本TLS 协议),并避免 hardcoding/specifying 在应用程序代码中使用明确的 TLS 版本。
Star配合 .NET Framework 4.7,默认配置是使用 OS TLS 版本。
其他可能有用的链接:https://github.com/dotnet/docs/issues/4675 and https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
不幸的是,这里的建议没有任何效果。
我在 github 上发现了一些关于类似问题的评论,以及如何将项目更新到 .NET core 3.1 来修复错误,所以我决定试一试...
这不是一项小工作,我在解决方案中有几个项目,但我可以确认,从 .NET core 2.1 更新到 .NET core 3.1 后,一切正常。