Search code examples
c#linuxasp.net-corecentos7exchangewebservices

EWS api - Unable to connect ExchangeServer on-prem


I am implementing the Microsoft EWS api in order to get emails from the on-prem Exchange Server. Considering that the Microsoft has abandoned the development, I am using the sherlock1982 fork from ews api. My app is written in .net core 2.1 and when running on my local PC (win10), everything is working well. Considering that its a Linux, it is not possible to automatically get the Autodiscover url, so I am manually setting it in the code, as suggested on the github page.

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}");
            }

        }

When deployed to the test server running CentOS7, I am getting following message:

The request failed. The SSL connection could not be established, see inner exception.

   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 

I have tried ignoring the certificate with ServicePointManager .ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

but without luck (I am getting the same error).

UPDATE: I have added a following piece of code

                ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
                {
                    if (cert.GetCertHashString().ToLower() == "someHashCert")
                    {
                       return true;
                    }

                    if (sslPolicyErrors == SslPolicyErrors.None)
                    {
                      
                        return true;   //Is valid
                    }

                    return false;
                }

inside the code for creating HttpClientHandler. Its entering inside the if "cert.GetCertHashString().ToLower()" which is good. I have copied the value of someHashCert from the browser. I also tried setting the

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

But error with this code (and above when checking the cert) is: The request failed. The handler does not support custom handling of certificates with this combination of libcurl (7.29.0) and its SSL backend ("NSS/3.44"). An SSL backend based on "OpenSSL/1.0.2k-fips" is required. Consider using System.Net.Http.SocketsHttpHandler.

If I set

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

I am getting: The request failed. GSSAPI operation failed with error - An unsupported mechanism was requested (Unknown error).

I have also tried to setup the callback for certificate from MS doc cert for ews api but then I am getting "Unable to get local issuer certificate" msg.

Not sure is this is step forward or backward... I have a feeling that I have tried everything...

UPDATE2 The ExchangeSever version is 2016, its using NTLM authentification and TLS1.0/1.1

I tried curl -v -k -i --anyauth -u : mail.server.domain:443 and it says

* 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: */*

Any idea is welcome... Thanks


Solution

  • Unfortunately, nothing suggested from here worked.

    I found some comment about similar issue on github and how updating the project to .NET core 3.1 fixed the error, so I decided to give it a try...

    It was not a small work, I had several projects inside the solution, but I can confirm that after updating from .NET core 2.1 to .NET core 3.1, everything is working as it should.