无法创建服务异常javax.xml.ws.WebServiceException:
我需要绝望的帮助来弄清楚为什么我的应用程序没有创建一个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==
java.security.cert.CertificateException: No subject alternative names present
这听起来像你直接使用IP地址连接(而不是主机名称)添加到没有“主题备用名称”条目的证书。
这当然涉及到这样一个问题:
如果您选择不使用SAN条目,但在CN依赖的主机名(你还配置为解析客户端中的正确IP地址),您还必须使用它来指定连接。您的URL构建器可能会构建仍依赖于IP地址的URL。
编辑:(以下评论)
正如我在回答刚才的链接另一个问题是说,有(至少)创建与主题Alt名称自签名证书的两种方法为Java:
- 使用Java 7的
keytool
- 使用OpenSSL的,如下所述:http://www.crsr.net/Notes/SSL.html
你已经选择了第二个选项(可能有点困难?)。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
我试图将它部署到另一台计算机上并指定一个主机名。它通过名称“找不到匹配的主机名”失败。实际上,在configureSSLConnection方法中,CNCheck被“tslClientParameters”禁用。setDisableCNCheck(true);“为什么它仍然失败?是这行:(service = new LoginWsService(buildURL(”LoginService“));)尝试建立一个SSL连接之前,它甚至配置正确? – Sapphire 2012-01-06 15:42:22
当然,如果你将它部署到另一台主机上(因为在你的例子中,IP地址是本地的),你需要每个客户端都知道这个名字,如果你使用的是主机名,一个IP地址直接,证书必须有一个符合规范的SAN条目(参见RFC 2818,Java实现)(我已经回答了你在上一个问题中如何解决这个问题)。使用SSL/TLS没有意义你不检查服务器的身份(在SAN或CN中),顺便说一下 – Bruno 2012-01-06 15:58:01
我遵循了这个页面上的所有步骤:http://www.crsr.net/Notes/SSL.html – Sapphire 2012-01-06 16:27:52
已发布的证书有问题。
我可以直接通过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工具的新密钥库,你应该没有问题。
您拥有服务器代码和客户端代码吗?您是如何创建证书的?你可以在服务器上贴上服务器证书吗? – Cratylus 2012-01-06 20:04:34
@ user384706刚添加它。我按照此链接中的说明创建了证书[http://www.crsr.net/Notes/SSL.html] – Sapphire 2012-01-06 20:12:18
@ Sapphire:检查我的答案 – Cratylus 2012-01-06 20:41:23