EWS api - невозможно подключить ExchangeServer на локальной машине - PullRequest
0 голосов
/ 07 августа 2020

Я использую Microsoft EWS api, чтобы получать электронные письма с локального сервера Exchange. Учитывая, что Microsoft отказалась от разработки, я использую вилку sherlock1982 из ews api . Мое приложение написано на. net core 2.1 и при работе на моем локальном P C (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 

Я пробовал игнорировать сертификат с помощью ServicePointManager .ServerCertificateValidationCallback + = (sender, cert, chain, 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"). Требуется серверная часть SSL на основе OpenSSL / 1.0.2k-fips. Рассмотрите возможность использования System. Net .Http.SocketsHttpHandler.

Если я установил

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true);

, я получаю: запрос не выполнен. Операция GSSAPI завершилась ошибкой - был запрошен неподдерживаемый механизм (неизвестная ошибка).

Я также пытался настроить обратный вызов для сертификата от MS do c cert для ews api , но затем Я получаю сообщение «Невозможно получить сертификат местного эмитента».

Не уверен, это шаг вперед или назад ... У меня такое ощущение, что я перепробовал все ...

UPDATE2 Версия 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: */*

Любая идея приветствуется ... Спасибо

Ответы [ 2 ]

1 голос
/ 16 августа 2020

К сожалению, ничего из предложенного здесь не сработало.

Я нашел комментарий об аналогичной проблеме на github и о том, как обновление проекта до. NET core 3.1 исправило ошибку, поэтому я решил попробовать ...

Это была не маленькая работа, у меня было несколько проектов внутри решения, но я могу подтвердить, что после обновления с. NET core 2.1 на. NET core 3.1 все работает как это должно быть.

0 голосов
/ 14 августа 2020

Обновите TLS на Cent OS. TLSv1.2 должен быть доступен в CentOS 7.

Некоторая документация.

Linux OpenSSL 1.1.1 поддерживает TLS v1.3 в разных Linux ОС.

RHEL 8 - Red Hat Enterprise Linux 8 - это первый дистрибутив Enterprise Linux, который поставляется с протоколом TLS v1.3, полностью интегрированным в операционную систему.

Старые версии CentOS и RHEL В версиях ОС по умолчанию установлен OpenSSL v1.0.2, поэтому TLS v1.3 изначально не поддерживается. OpenSSL можно yum обновить до OpenSSL v1.1.1 для поддержки TLS v1.3.

Blockquote

Как установить OpenSSL v1.1.1 на CentOS RedHat Linux: Используйте команду OpenSSL Version для проверки версии OpenSSL:

openssl version

Установите wget (если он не установлен):

yum install 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 в системе для тестирования, тогда

TLS должен поддерживаться ОС и. net framework. Проверьте ОС и обновите ее, если она не поддерживает TLS 1.2, затем используйте платформу Right. net, которая поддерживает TLS 1.2 / 1.3. Установите самоподписанный сертификат также на Cent OS.

Будет ли TLS 1.3 поддерживаться. NET?

Для. NET официальное руководство на этом этапе (с помощью страницы с рекомендациями выше) заключается в том, чтобы полагаться на базовую ОС для предоставления версии TLS (которая автоматически по умолчанию будет использовать самую надежную доступную версию протокола TLS) и избегайте жесткого кодирования / указания явной версии TLS в коде приложения.

Начиная с. NET Framework 4.7, в конфигурации по умолчанию используется версия OS TLS.

Другие ссылки, которые могут быть полезны: https://github.com/dotnet/docs/issues/4675 и https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls

...