无法创建服务异常javax.xml.ws.WebServiceException:

发布于 2024-12-25 16:25:34 字数 4757 浏览 1 评论 0原文

我需要迫切的帮助来弄清楚为什么我的应用程序没有创建网络服务。

这是我的 webservice 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"));
}
}

调用此服务的代码是:

  public static LoginWs getLoginWs()
{

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

    LoginWs port = service.getLoginWsPort();

    CxfClientUtils.configureClientConnection(port);

    return(port);
}

抛出异常:

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

这是完整的异常:

    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 服务 = new 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

与服务器实际使用的内容相比:

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

I need desperate help to figure out why my application is not creating a webservice.

Here's my webservice Java class:

  @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"));
}
}

The code that is calling this service is:

  public static LoginWs getLoginWs()
{

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

    LoginWs port = service.getLoginWsPort();

    CxfClientUtils.configureClientConnection(port);

    return(port);
}

The exception is thrown at :

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

Here is the full exception:

    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

Can someone tell me why it is failing at creating Service itself. In LoginWs method, this line

   CxfClientUtils.configureClientConnection(port);

configures the SSL connection but my code is not even getting there. It's trying to connect at
LoginWsService service = new LoginWsService(buildURL("LoginService"));
and failing.

Can someone please tell me what's going on here? Thanks!

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 what the server is actually using:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鸢与 2025-01-01 16:25:34
java.security.cert.CertificateException: No subject alternative names present

听起来您正在使用 IP 地址(而不是主机名)直接连接到没有主题备用名称条目的证书。

这当然与这个问题有关:

如果您选择不使用 SAN 条目,而是依赖 CN 中的主机名(您还配置了在客户端中解析为正确的 IP 地址),您还必须使用它来指定连接。您的 URL 构建器可能正在构建仍然依赖于 IP 地址的 URL。

编辑:(以下评论)

正如我在回答上面链接的另一个问题时所说的那样,(至少)有两种方法可以使用 Java 主题替代名称创建自签名证书:

您选择了第二个选项(可能有点困难?)。 OpenSSL 能够生成 PKCS#12 文件 (.p12),默认的 Java 安全提供程序应该能够直接将其用作密钥库(尽管 Java 6 中的 keytool以上能够通过 -importkeystore 将它们转换为 JKS 存储。要直接使用它们,请使用“PKCS12”存储类型。

使用 OpenSSL,使用自签名证书生成的结果构建 PKCS#12 文件(假设证书的文件名为 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
java.security.cert.CertificateException: No subject alternative names present

It sounds like you're connecting using an IP address directly (and not a host name) to a certificate that doesn't have a Subject Alternative Name entry.

This is of course related to this question:

If you've chosen not to use a SAN entry but to rely an a host name in the CN (which you've also configured to resolve to the correct IP address in your client), you must also use it to specify the connection. Your URL builder is probably building a URL that still relies on the IP address.

EDIT: (Following comments)

As I was saying in the answer to the other question linked above, there are (at least) two ways of creating a self-signed cert with a Subject Alt Name for Java:

You've chosen the second option (possibly a bit more difficult?). OpenSSL is capable of producing a PKCS#12 file (.p12), which the default Java security providers should be able to use as a keystore directly (although keytool in Java 6 and above is capable of converting them to a JKS store via -importkeystore). To use them directly, use the "PKCS12" store type.

To build a PKCS#12 file, with OpenSSL, using the result of the self-signed certificate generation (assuming the files are called cert.pem for the cert and key.pem for the private key):

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

Then, configure it in Apache Tomcat using (and restart Tomcat):

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

To extract the content of the cert in the PKCS#12 file:

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

To check the certificate the server is actually using:

echo "" | openssl s_client -showcerts -connect hostname_or_ip_address:port
宁愿没拥抱 2025-01-01 16:25:34

您发布的证书有问题。

我可以直接通过 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 解码时出现问题。
尝试 Bouncy Castle 它也无法读取它。

我之前就看到过安全库和 Windows 能够解码证书,而 Java 库则不能的这种差异。

在您的情况下,您的证书无法被使用 java 的 Web 服务客户端解析,并且 CXF 包装器引发的异常包含有关主题备用名称的误导性消息。

我无法判断您的证书有什么问题,因为我对 open ssl 不太熟悉。

但是如果你使用java工具创建(只是为了验证我所说的)一个新的密钥库,你应该没有问题。

The certificate you have posted has an issue.

I can open it directly via Windows and I bet if you open Internet Explorer and type the web service URL and view the certificate via IE you should not have any issue.

BUT for some reason Java can not parse it.
For example if I try to read the certificate via default java libraries:

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

}

I get parsing exception:

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

There is a problem in the decoding from base64.
Trying Bouncy Castle it failed to read it as well.

I have seen before this discrepancy between security libraries and Windows being able to decode certificates while Java's libraries can not.

In your case, your certificate can not be parsed by your web service client that uses java and the exception thrown up from CXF wrappers has the missleading message about subject alternative names.

I can not tell what is the problem with your certificate because I am not very familiar with open ssl.

But if you create (just to verify what I am saying) a new keystore using java tools you should have no problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文