Can't call EWS service with API Java SSL and certificates

5k views Asked by At

I am actually working on EWS Java API. The goal is to access data in the Calendar. So I started learning how to use the EWS Java API.

Begining with a sample example, I found some problems :

ExchangeService service = new ExchangeService();
        ExchangeCredentials credentials = new WebCredentials("[email protected]",  "password");    
        service.setCredentials(credentials);            
        //WebProxy webProxy = new WebProxy("proxy.domain.company", 8080);
        //There's no credentials for the proxy 
        //service.setWebProxy(webProxy);  
        try {
            service.setUrl(new URI("https://domain.company/ews/exchange.asmx"));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }    
        EmailMessage msg;
        try {
            msg = new EmailMessage(service);
            msg.setSubject("hello world");
            msg.setBody(MessageBody.getMessageBodyFromText("Sent using the EWS API"));
            msg.getToRecipients().add("[email protected]");
            msg.send();
        } catch (Exception e) {
            e.printStackTrace();
        }

Executing the code gave me at first errors related to dependencies at first then to certifications and SSL at a second time and here's a trace of the console :

    ------------------------------------------------------------------------
    Building ol-v01 1.0-SNAPSHOT
    ------------------------------------------------------------------------

    --- exec-maven-plugin:1.2.1:exec (default-cli) @ ol-v01 ---
    microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. The request failed. sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.int...
    Caused by: microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    ....
    ... 38 more
    ------------------------------------------------------------------------
    BUILD SUCCESS
    ------------------------------------------------------------------------
    Total time: 7.891s
    Finished at: Tue Jun 09 17:49:04 CEST 2015
    Final Memory: 5M/119M
    ------------------------------------------------------------------------

Si I am trying to sove this issue :

I found some questions with the same problem, and I followed the steps to install the certifcate downloaded from the browser with keytool under JAVA_HOME\lib\security\cacerts

And I added it to with the mmc.exe tool under Third party Certificate Authorities.

So I can see that the installed certificate

Is there any way to solve this? is there a step that I didn't proceed? also I want to know if EWS let me to disable SSL checking?

NB : The server is the Entreprise Exchange 2010 SP2, so I will use my account to test, also I installed a local server on VM to see the difference and the problems because I have some problems with the proxy.

Also, I want to know if the administrator of the Server needs to activate something to use the EWS ?

Thanks for your help.

Update 2

Here's the results after installing my own Exchange 2010 server on MS Server 2012 VM.

I can access OWA via https://192.168.1.59/owa/

As followed in some questions and tutorials, I exported the certificate from browser to a file. The name is verifyfail.WIN-NS09AI4QBB8 and the CN = verifyfail.WIN-NS09AI4QBB8

I don't know why this name but it's ok.

The filename is verifyfail.WIN-NS09AI4QBB8.cer

Then I used the keytool to add this certificate to JAVA_HOME\lib\security\cacerts. I used as alias verifyfail.WIN-NS09AI4QBB8.

Also I added it to with the mmc.exe tool under Third party Certificate Authorities.

The code bcomes like this :

    ExchangeService service = new ExchangeService();
    ExchangeCredentials credentials = new WebCredentials("[email protected]",  "P@ssw0rd");
    service.setCredentials(credentials);                 
    try {
        service.setUrl(new URI("https://192.168.1.59/ews/exchange.asmx"));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    EmailMessage msg;
    try {
        msg = new EmailMessage(service);
        msg.setSubject("hello world");
        msg.setBody(MessageBody.getMessageBodyFromText("Sent using the EWS API"));
        msg.getToRecipients().add("[email protected]");
        msg.send();
    } catch (Exception e) {
        e.printStackTrace();
    }

My POM file contains these dependencies :

    <dependency>
        <groupId>com.microsoft.ews-java-api</groupId>
        <artifactId>ews-java-api</artifactId>
        <version>2.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.4.1</version>
    </dependency>

As output, I got this error : The request failed. The request failed. Host name '192.168.1.59' does not match the certificate subject provided by the peer (CN=WIN-NS09AI4QBB8)

And the trace of execution :

------------------------------------------------------------------------
Building ol-v01 1.0-SNAPSHOT
------------------------------------------------------------------------

--- exec-maven-plugin:1.2.1:exec (default-cli) @ ol-v01 ---
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. The request failed. Host name '192.168.1.59' does not match the certificate subject provided by the peer (CN=WIN-NS09AI4QBB8)
    at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:74)
    at microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:158)
    at microsoft.exchange.webservices.data.core.ExchangeService.internalCreateItems(ExchangeService.java:594)
    at microsoft.exchange.webservices.data.core.ExchangeService.createItem(ExchangeService.java:653)
    at microsoft.exchange.webservices.data.core.service.item.Item.internalCreate(Item.java:245)
    at microsoft.exchange.webservices.data.core.service.item.EmailMessage.internalSend(EmailMessage.java:147)
    at microsoft.exchange.webservices.data.core.service.item.EmailMessage.send(EmailMessage.java:258)
    at com.soprahr.ol.v01.T10.testMethod(T10.java:46)
    at com.soprahr.ol.v01.T10.main(T10.java:24)
Caused by: microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. Host name '192.168.1.59' does not match the certificate subject provided by the peer (CN=WIN-NS09AI4QBB8)
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.getEwsHttpWebResponse(ServiceRequestBase.java:729)
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.validateAndEmitRequest(ServiceRequestBase.java:639)
    at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:62)
    ... 8 more
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Host name '192.168.1.59' does not match the certificate subject provided by the peer (CN=WIN-NS09AI4QBB8)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134)
    at org.apache.http.impl.conn.BasicHttpClientConnectionManager.connect(BasicHttpClientConnectionManager.java:338)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at microsoft.exchange.webservices.data.core.request.HttpClientWebRequest.executeRequest(HttpClientWebRequest.java:292)
    at microsoft.exchange.webservices.data.core.request.ServiceRequestBase.getEwsHttpWebResponse(ServiceRequestBase.java:720)
    ... 10 more
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 2.145s
Finished at: Wed Jun 10 04:34:14 CEST 2015
Final Memory: 5M/119M
------------------------------------------------------------------------

Update 3

In the detail tab of the certificate, the Oject Key has as value CN = verifyfail.WIN-NS09AI4QBB8 which is different to CN=WIN-NS09AI4QBB8

The certificate that I download using the browser contains verifyfail.WIN-NS09AI4QBB8.

In this case, what should I do to avoid this problem ?

enter image description here

4

There are 4 answers

0
vzamanillo On

The error is related to a DNS problem or a problem with the name in the server certificate.

Make sure that the name in the CN attribute of the certificate (WIN-NS09AI4QBB8) is resolvable and returns the correct IP address (192.168.1.59).

The name in the CN attribute value must resolve in DNS to the IP address of the server. The error message

The request failed. The request failed. Host name '192.168.1.59' does not match the certificate subject provided by the peer (CN=WIN-NS09AI4QBB8)

occurs because the DNS name can not be resolved, or resolves to a wrong IP.

0
Jordan On

in the url, do not use ip, insteaded by hostname,eg. https://172.50.1.73/owa, insteaded by https://exchange/owa, at here you should write the mapping relation to the hosts file, eg. 172.50.1.73 exchange;

0
Vlado Lesko On

I have manually downloaded cerificate and imported it into my keystore using command : keytool -importcert -file nameofCertificate.(crt|cert) -keystore key store.jks -alias "EWScert" then i added this command to my code System.setProperty("javax.net.ssl.trustStore",CERTIFICATION_FILE); CERTIFICATION_FILE is path to to your cert file for me it is located in C:\Program Files\Java\jre1.8.0_121\lib\security\cacerts

and all this steps solved my problem

0
Roma Kap On

I have same problem. I have download my certificate and imported this into keystore. Whithin my code i say:

    systemProps.put(
            "javax.net.ssl.trustStore",
            "C:/Program Files/Java/jdk1.8.0/jre/lib/security/cacerts"
        );

    systemProps.put("javax.net.ssl.trustStorePassword","changeit");



    System.setProperties(systemProps);

When i set url manualy: i get this error:

ServiceRequestException: The request failed. The request failed. The remote server returned an error: (401)Unauthorized

And when i use autodiscover, i cant find any endpoints:

Type:AutodiscoverConfiguration Message: Determining which endpoints are enabled for host mycompany.com

Type:AutodiscoverConfiguration Message: Host returned enabled endpoint flags: [Legacy]

Type:AutodiscoverConfiguration Message: No Autodiscover endpoints are available for host mycompany.com