2014-01-11 5 views
0

У меня возникла странная проблема с приложением JSF, над которым я сейчас работаю. Кажется, что есть две части моей программы, которые сталкиваются.Проблемы с JavaMail после использования хранилища ключей

Есть две части:

  • «Банковские» функциональность
  • почты функциональность

Соответствующая часть банковской функциональности (Это фальшивый банк только для этого упражнения):

String path = FacesContext.getCurrentInstance().getExternalContext()    .getRealPath("/") + "/WEB-INF/sec/certs.jks"; 

ErrorHandler.trace(path); 

System.setProperty("javax.net.ssl.trustStore", path); 

Здесь он устанавливает Trust Store с сертификатом для банковского сервера.

почта часть выглядит следующим образом:

Properties props = new Properties(); 
props.put("mail.smtp.auth", this.smtpServer.isAuthenticated()); 
props.put("mail.smtp.starttls.enable", this.smtpServer.isTls()); 
props.put("mail.smtp.host", this.smtpServer.getHostaddr()); 
props.put("mail.smtp.port", this.smtpServer.getPort()); 
props.put("mail.smtps.auth", "true"); 
props.put("mail.smtp.debug", "true"); 

final String username = this.smtpServer.getUsername(); 
final String password = this.smtpServer.getPassword(); 

Session session = Session.getDefaultInstance(props, 
     new javax.mail.Authenticator() { 
      @Override 
      protected PasswordAuthentication getPasswordAuthentication() { 
       return new PasswordAuthentication(username, password); 
      } 
     }); 

session.setDebug(true); 

Один способ воспроизвести проблему:

Проблема я столкнулся в том, что, если я запустить приложение и, например, , используйте функциональность «изменить почту», я немедленно отправлю уведомление. Нет проблем. Затем я попытаюсь купить продукт, тем самым активируя функциональность банка.

Вот где проблема проявляется:

Communication Error: javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException 
- with linked exception: 
[javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target] 

Другой способ воспроизвести проблему:

Теперь давайте говорить, что я перезагрузить приложение и попытаться заказать что-нибудь, на этот раз он будет работать но функциональность почты нарушается с этим сообщением об ошибке:

DEBUG: setDebug: JavaMail version 1.4.7 
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle] 
DEBUG SMTP: useEhlo true, useAuth true 
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 465, isSSL true 
TRACE Error Could not connect to SMTP host: smtp.gmail.com, port: 465 

Нижняя линия :

Если я запустить банк, а затем по почте -> почта не работает Если я вызвать почту, а затем банк -> банк не работает

Любой, кто мог бы найти проблему там?

Спасибо!

+0

Может JavaMail является заходящего доверие хранить на другом пути. Вы можете проверить это через 'System.getProperty (" javax.net.ssl.trustStore ");' после отправки почты. – unwichtich

+0

Я добавил некоторые отладочные данные в почту и методы заказа, и это всегда один и тот же магазин доверия: 'my/path/Eclipse/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/MyApp // WEB-INF/sec/certs.jks' – mediocre

ответ

1

Ваши «банковские функции» меняют хранилище доверия. Это новое хранилище доверия должно иметь сертификаты, необходимые для проверки SSL-соединения с вашим почтовым сервером. Вы можете инициализировать хранилище доверенных сертификатов всеми сертификатами CA из хранилища доверия по умолчанию JDK или добавить только специальный сертификат для своего почтового сервера - см. Программу InstallCert. Наконец, вы можете настроить JavaMail на использование отдельного хранилища доверия или изменить свою банковскую функциональность, чтобы использовать хранилище доверия явно, а не переопределять хранилище доверия по умолчанию; они, вероятно, более сложны.

+0

Спасибо! Я добавил default keyStore в свой собственный keyStore, и теперь он работает. – mediocre

0

Проблема заключалась в том, что функциональность почты работает, если нет набора доверенных сертификатов (потому что с помощью по умолчанию доверенных сертификатов системы, которая находится в:.

/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/security/cacerts 

на Mac

Функциональность банковской использует свой собственный сертификат, который был расположен в:

MyProject/.../WEB-INF/sec/certs.jks 

Каждый раз, когда JavaMail пытался пройти проверку подлинности на SMTP сервере, то синтаксического дерева от Google d, чтобы использовать certs.jks trustStore, даже если я отключил свойство trustStore, функциональность банковского обслуживания, установленную в методе почты.

Fix:

В начале метода почты:

String path = FacesContext.getCurrentInstance().getExternalContext() 
      .getRealPath("/") 
      + "WEB-INF/sec/certs.jks"; 
System.setProperty("javax.net.ssl.trustStore", path); 

импорта по умолчанию cacerts хранилищу в наш собственный пользовательский хранилище ключей:

keytool -importkeystore -srckeystore certs.jks -destkeystore cacerts 
Смежные вопросы