2012-01-06 108 views
0

我需要絕望的幫助來弄清楚爲什麼我的應用程序沒有創建一個web服務。無法創建服務異常javax.xml.ws.WebServiceException:

這裏是我的web服務的Java類:

@WebService 
    @Component 
    public class LoginWs extends AbstractWs 
{ 
private static final Logger logger=MiscUtils.getLogger(); 

@Autowired 
private PersonDao personDao = null; 

/** 
* Returns PersonTransfer on valid login 
* @throws NotAuthorisedException if password is incorrect 
*/ 
public PersonTransfer login(String userNameOrEmailAddress, String password) throws NotAuthorisedException 
{ 
    Person person=personDao.findByUserNameOrEmailAddress(userNameOrEmailAddress, true); 

    if (person != null && person.checkPassword(password)) 
    { 
     PersonTransfer personTransfer = PersonTransfer.getTransfer(person); 

     personDao.setLastLogin(person.getId(), new GregorianCalendar()); 

     EventLogDao.logEvent(ActionType.READ_DATA.name(), "LoginWs.login()", "personId=" + person.getId());   

     return(personTransfer); 
    } 

    logger.debug("Login failed : u/p="+userNameOrEmailAddress+"/"+password); 

    throw(new NotAuthorisedException("Invalid Username/Password")); 
} 
} 

正在調用該服務的代碼是:

LoginWsService service = new LoginWsService(buildURL("LoginService")); 

以下是完整的:

public static LoginWs getLoginWs() 
{ 

    LoginWsService service = new LoginWsService(buildURL("LoginService")); 

    LoginWs port = service.getLoginWsPort(); 

    CxfClientUtils.configureClientConnection(port); 

    return(port); 
} 

的例外是在拋出例外:

Error 
    javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service. 
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149) 
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:65) 
at javax.xml.ws.Service.<init>(Service.java:56) 
at org.websr.my_server.ws.LoginWsService.<init>(Unknown Source) 

    Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://192.168.2.184:8443/my_server/ws/LoginService?wsdl'.: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present 

有人可以告訴我爲什麼它創建服務本身失敗。在LoginWs方法中,這條線

CxfClientUtils.configureClientConnection(port); 

配置SSL連接,但我的代碼甚至沒有達到那裏。它試圖連接在 LoginWsService服務=新的LoginWsService(buildURL(「LoginService」)); 並失敗。

有人能告訴我這裏發生了什麼事嗎?謝謝!

cert.pem:

 MIID1DCCArygAwIBAgIJAPAlC2JvlPsZMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD 
VQQGEwJDQTEQMA4GA1UECBMHT250YXJpbzEQMA4GA1UEBxMHVG9yb250bzERMA8G 
A1UEChMISW5kaXZpY2ExETAPBgNVBAsTCEluZGl2aWNhMRYwFAYDVQQDEw0xOTIu 
MTY4LjIuMTg0MSEwHwYJKoZIhvcNAQkBFhJkaXZ5YUBpbmRpdmljYS5jb20wHhcN 
MTIwMTA2MTYxMTQwWhcNMTMwMTA1MTYxMTQwWjCBkjELMAkGA1UEBhMCQ0ExEDAO 
BgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xETAPBgNVBAoTCEluZGl2 
aWNhMREwDwYDVQQLEwhJbmRpdmljYTEWMBQGA1UEAxMNMTkyLjE2OC4yLjE4NDEh 
MB8GCSqGSIb3DQEJARYSZGl2eWFAaW5kaXZpY2EuY29tMIIBIjANBgkqhkiG9w0B 
AQEFAAOCAQ8AMIIBCgKCAQEAxY8+fsw2pP4ToHN6XFNli4vOGbt+O/ANsr1A8iJh 
nCb6cpQ58xF4pvYmETHrAUpv4zpi31SzZvWYI1tMaCEv9IpcX6Kc1B8NB9sLUnhR 
gyblF37rZ7eMmSAXXeDS0CTtDEJoHOkGxoUdCN6N+vZjJ5+ZONiiuLqZ4x4HwBFr 
ucIlwl2FkMMSxylg90tttSIyUHGz/p2DvNA2goYih4d89c/FLNpqwku+G3/gnL7U 
l0OmNuFwJa/qMjy/V1orfpT8egxxh8DMp+fLAv1gjbeoizUs2bHo9kQSbUSp9Cwb 
VDCol9jGI14cBuuEpWSANx2gTekN1ktoxztFPCh7H3OK/wIDAQABoyswKTAPBgNV 
HREECDAGhwTAqAK4MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMA0GCSqGSIb3DQEB 
BQUAA4IBAQALvpU0/5gQedlET2+r2MV0oksTmM2hV677yVsrOnGCOnTcgMZHp5i4 
A0B24Ed2iDesX60OAViIocQkOiwYTRnubg5SoWyL1nhmaa/98U6M/re8R/bvq6OK 
qrzEO6hHOtunJg1HcZDiJZop7R/pM52yRhRoXU6upZEhbPr6Eh+zfysA0TD6uMs7 
9k2VeJo++XUvbG3dkVJ9kYhqfx2vC0HiMI4H2eomzl2ymS+R9Kg/9o29K8oCYjDI 
jWPbl2hmf2cQuC4gG8GUDZi7zJkFsBuJpD6XgpIVK9zNhg1e89eP0nABupIFqBOI 
iz0C+tRB4z4TezPL6yC7BDMY2nJ/Cg5e 

VS是服務器的實際使用:

MIICVTCCAb6gAwIBAgIETr3AxTANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJD 
QTEQMA4GA1UECBMHT250YXJpbzEQMA4GA1UEBxMHVG9yb250bzERMA8GA1UEChMI 
SW5kaXZpY2ExETAPBgNVBAsTCEluZGl2aWNhMRYwFAYDVQQDEw0xOTIuMTY4LjIu 
MTg0MB4XDTExMTExMjAwNDE0MVoXDTIxMTEwOTAwNDE0MVowbzELMAkGA1UEBhMC 
Q0ExEDAOBgNVBAgTB09udGFyaW8xEDAOBgNVBAcTB1Rvcm9udG8xETAPBgNVBAoT 
CEluZGl2aWNhMREwDwYDVQQLEwhJbmRpdmljYTEWMBQGA1UEAxMNMTkyLjE2OC4y 
LjE4NDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzvnBMOM2YpM4Ch0MkesA 
ryqX3YD8O22kJJrpRuOMyqgt6fKEDxkcGjiEZ7qLfWbzv3eX9DE0nVeS4m65Ucr2 
LLZN6iZoqP8J+AmkSXKapIQpX7tZM5UuTDy82vUdOiYJELB3NSJc/4nkZkTaN8Uj 
h3Ph366kRUP+QWiq2y97KKMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBFeOQOKq9u 
4nq/IUgNpILrhcpiAP5LB49bCXeTCi8Ls51qUCaezceUQKrWM60a6w8FxQF+yopB 
PSqGMrUBHnvewkThgZbS12t5vOEoXnWjOwiXhMhRsk5i9YUh1QCYfOFF23aXNfRu 
NLL5svksUHm1IzBJJANnL/YdJHRrR0IEQg== 
+0

您擁有服務器代碼和客戶端代碼嗎?您是如何創建證書的?你可以在服務器上貼上服務器證書嗎? – Cratylus 2012-01-06 20:04:34

+0

@ user384706剛添加它。我按照此鏈接中的說明創建了證書[http://www.crsr.net/Notes/SSL.html] – Sapphire 2012-01-06 20:12:18

+0

@ Sapphire:檢查我的答案 – Cratylus 2012-01-06 20:41:23

回答

4
java.security.cert.CertificateException: No subject alternative names present 

這聽起來像你直接使用IP地址連接(而不是主機名稱)添加到沒有「主題備用名稱」條目的證書。

這當然涉及到這樣一個問題:

如果您選擇不使用SAN條目,但在CN依賴的主機名(你還配置爲解析客戶端中的正確IP地址),您還必須使用它來指定連接。您的URL構建器可能會構建仍依賴於IP地址的URL。

編輯:(以下評論)

正如我在回答剛纔的鏈接另一個問題是說,有(至少)創建與主題Alt名稱自簽名證書的兩種方法爲Java:

你已經選擇了第二個選項(可能有點困難?)。OpenSSL能夠生成一個PKCS#12文件(.p12),默認的Java安全提供程序應該能夠直接用作密鑰庫(儘管在Java 6及更高版本中的keytool能夠通過-importkeystore將它們轉換爲JKS存儲庫)。要直接使用它們,請使用"PKCS12"商店類型。

要建立一個PKCS#12文件,使用OpenSSL,使用自簽名證書生成的結果(假設文件被稱爲cert.pem的證書和key.pem私鑰):

openssl pkcs12 -export -in cert.pem -inkey key.pem -out store.p12 

然後,使用的Apache Tomcat配置它(並重新啓動Tomcat):

<Connector port="8443" ... scheme="https" secure="true" 
    keystoreFile="/path/to/store.p12" 
    keystorePass="..." keystoreType="PKCS12" sslProtocol="TLS" /> 

要提取證書中的PKCS內容#12文件:

openssl pkcs12 -in store.p12 -nokeys -clcerts | openssl x509 -text -noout 

要檢查證書的服務器實際使用:

echo "" | openssl s_client -showcerts -connect hostname_or_ip_address:port 
+0

我試圖將它部署到另一臺計算機上並指定一個主機名。它通過名稱「找不到匹配的主機名」失敗。實際上,在configureSSLConnection方法中,CNCheck被「tslClientParameters」禁用。setDisableCNCheck(true);「爲什麼它仍然失敗?是這行:(service = new LoginWsService(buildURL(」LoginService「));)嘗試建立一個SSL連接之前,它甚至配置正確? – Sapphire 2012-01-06 15:42:22

+0

當然,如果你將它部署到另一臺主機上(因爲在你的例子中,IP地址是本地的),你需要每個客戶端都知道這個名字,如果你使用的是主機名,一個IP地址直接,證書必須有一個符合規範的SAN條目(參見RFC 2818,Java實現)(我已經回答了你在上一個問題中如何解決這個問題)。使用SSL/TLS沒有意義你不檢查服務器的身份(在SAN或CN中),順便說一下 – Bruno 2012-01-06 15:58:01

+0

我遵循了這個頁面上的所有步驟:http://www.crsr.net/Notes/SSL.html – Sapphire 2012-01-06 16:27:52

1

已發佈的證書有問題。

我可以直接通過Windows打開它,我敢打賭,如果您打開Internet Explorer並鍵入Web服務URL並通過IE查看證書,您應該沒有任何問題。

但是由於某種原因,Java無法解析它。
例如,如果我嘗試通過默認的Java庫讀取證書:

public static void main(String[] args) throws Exception{ 

CertificateFactory f = CertificateFactory.getInstance("X.509"); 
X509Certificate certificate = (X509Certificate) f.generateCertificate(new FileInputStream("C:\\certificate.pem")); 
System.out.println(certificate); 

} 

我得到解析異常:

Exception in thread "main" java.security.cert.CertificateException: Could not parse certificate: java.io.IOException: Unsupported encoding 
    at sun.security.provider.X509Factory.engineGenerateCertificate(Unknown Source) 
    at java.security.cert.CertificateFactory.generateCertificate(Unknown Source) 
    at test.Test.main(Test.java:15) 
Caused by: java.io.IOException: Unsupported encoding 
    at sun.security.provider.X509Factory.base64_to_binary(Unknown Source) 
    ... 3 more 

有從BASE64解碼的問題。
嘗試充氣城堡它沒有閱讀它。

在安全庫和Windows能夠解碼證書而Java不能解碼證書之前,我已經看到這種差異。

在你的情況下,你的證書不能被你的使用java的web服務客戶端解析,並且從CXF包裝器拋出的異常有關於使用者替代名稱的錯誤消息。

我不能告訴你的證書有什麼問題,因爲我不太熟悉打開ssl。

但是,如果你創建(只是爲了驗證我在說什麼)使用java工具的新密鑰庫,你應該沒有問題。

+0

這一切都是從使用Java keytool創建密鑰庫開始,然後是這是拋出「主題替代名稱」錯誤,所以我訴諸創建一個新的密鑰庫openssl使用主題替代名稱爲IP:192.168.2.184。 – Sapphire 2012-01-06 20:46:24

+0

我是對的,你可以使用IE連接並看到證書? – Cratylus 2012-01-06 20:57:35

+0

我在Mac上,我的客戶端和服務器應用程序部署在遠程ubuntu機器上 – Sapphire 2012-01-06 21:00:21

相關問題