2014-01-11 32 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連接所需的證書。您可以使用JDK默認信任庫中的所有CA證書初始化您的信任庫,也可以只爲您的郵件服務器添加特定證書 - 請參閱InstallCert程序。最後,您可以將JavaMail配置爲使用單獨的信任庫,或將您的銀行功能更改爲明確使用信任庫,而不是覆蓋默認信任庫;那些可能更復雜。

+0

謝謝!我添加了默認的keyStore到我自己的keyStore,現在它正在工作。 – mediocre

0

的問題是,該郵件功能是工作,如果沒有的trustStore集(因爲它是用它位於系統的默認的trustStore:

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

在Mac上

的銀行功能在使用它自己的證書這是位於:

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

每次的JavaMail試圖驗證到谷歌的SMTP服務器是特里d以使用certs.jks trustStore,即使我未設置trustStore屬性在郵件方法中設置的銀行功能。

修復:

在郵件方法的開頭:

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

導入默認cacerts的keyStore到我們自己的自定義密鑰庫:

keytool -importkeystore -srckeystore certs.jks -destkeystore cacerts