Не удается вызвать службу EWS с API Java SSL и сертификатами

Я на самом деле работаю над EWS Java API. Цель - получить доступ к данным в календаре. Поэтому я начал изучать, как использовать API Java EWS.

Начав с примера, я обнаружил некоторые проблемы:

ExchangeService service = new ExchangeService();
        ExchangeCredentials credentials = new WebCredentials("me@company.com",  "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("my.boss@company.com");
            msg.send();
        } catch (Exception e) {
            e.printStackTrace();
        }

Выполнение кода сначала дало мне ошибки, связанные с зависимостями, а затем с сертификатами и SSL во второй раз, и вот след консоли:

    ------------------------------------------------------------------------
    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
    ------------------------------------------------------------------------

Я пытаюсь решить эту проблему:

Я нашел несколько вопросов с той же проблемой, и я следовал инструкциям по установке сертификата, загруженного из браузера с помощью keytool JAVA_HOME\lib\security\cacerts

И я добавил это с mmc.exe инструмент под Сторонними центрами сертификации.

Итак, я вижу, что установленный сертификат

Есть ли способ решить это? Есть ли шаг, который я не продолжил? также я хочу знать, позволяет ли EWS отключать проверку SSL?

NB. Сервером является Entreprise Exchange 2010 с пакетом обновления 2 (SP2), поэтому я буду использовать свою учетную запись для тестирования, также я установил локальный сервер на ВМ, чтобы увидеть разницу и проблемы, потому что у меня есть некоторые проблемы с прокси.

Кроме того, я хочу знать, должен ли администратор Сервера активировать что-либо для использования EWS?

Спасибо за вашу помощь.

Обновление 2

Вот результаты после установки моего собственного сервера Exchange 2010 на виртуальной машине MS Server 2012.

Я могу получить доступ к OWA через https://192.168.1.59/owa/

Как и в некоторых вопросах и руководствах, я экспортировал сертификат из браузера в файл. Имя verifyfail.WIN-NS09AI4QBB8 и CN = verifyfail.WIN-NS09AI4QBB8

Я не знаю, почему это имя, но это нормально.

Имя файла - verifyfail.WIN-NS09AI4QBB8.cer.

Затем я использовал keytool для добавления этого сертификата в JAVA_HOME\lib\security\cacerts. Я использовал как псевдоним verifyfail.WIN-NS09AI4QBB8,

Также я добавил его с помощью инструмента mmc.exe в разделе Сторонние центры сертификации.

Код получается так:

    ExchangeService service = new ExchangeService();
    ExchangeCredentials credentials = new WebCredentials("ab@domain.com",  "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("pp@domain.com");
        msg.send();
    } catch (Exception e) {
        e.printStackTrace();
    }

Мой файл POM содержит эти зависимости:

    <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>

В качестве вывода я получил эту ошибку: 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)

И след исполнения:

------------------------------------------------------------------------
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
------------------------------------------------------------------------

Обновление 3

На вкладке сведений сертификата ключ Oject имеет значение CN = verifyfail.WIN-NS09AI4QBB8, которое отличается от CN=WIN-NS09AI4QBB8.

Сертификат, который я загружаю с помощью браузера, содержит verifyfail.WIN-NS09AI4QBB8.

В этом случае, что я должен сделать, чтобы избежать этой проблемы?

4 ответа

Ошибка связана с проблемой DNS или с именем в сертификате сервера.

Убедитесь, что имя в CN attribute сертификата (WIN-NS09AI4QBB8) разрешаема и возвращает правильный IP-адрес (192.168.1.59).

Имя в значении атрибута CN должно преобразовываться в DNS в IP-адрес сервера. Сообщение об ошибке

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)

происходит, потому что DNS-имя не может быть разрешено или разрешается с неверным IP-адресом.

У меня такая же проблема. Я скачал свой сертификат и импортировал его в хранилище ключей. В своем коде я говорю:

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

Когда я устанавливаю URL вручную: я получаю эту ошибку:

ServiceRequestException: запрос не выполнен. Ошибка запроса. Удаленный сервер возвратил ошибку: (401) Несанкционированный

И когда я использую автообнаружение, я не могу найти какие-либо конечные точки:

Тип:AutodiscoverConfiguration Сообщение: определение того, какие конечные точки включены для хоста mycompany.com

Тип:AutodiscoverConfiguration Сообщение: Хост вернул включенные флаги конечной точки: [Legacy]

Тип:AutodiscoverConfiguration Сообщение: Нет конечных точек автообнаружения для хоста mycompany.com

В URL не используйте ip, вместо имени хоста, например. https://172.50.1.73/owa, вместо https://exchange/owa, здесь вы должны написать отношение отображения к файлу hosts, например. 172.50.1.73 обмен;

Я вручную загрузил сертификат и импортировал его в хранилище ключей с помощью команды: keytool -importcert -file nameofCertificate.(Crt|cert) -keyystore key store.jks -alias "EWScert", затем я добавил эту команду в свой код System.setProperty("javax.net.ssl.trustStore",CERTIFICATION_FILE); CERTIFICATION_FILE - это путь к файлу сертификата для меня, он находится в C:\Program Files\Java\jre1.8.0_121\lib\security\cacerts

и все эти шаги решили мою проблему

Другие вопросы по тегам