【问题标题】:Java Client for WCF on HTTPSHTTPS 上 WCF 的 Java 客户端
【发布时间】:2012-05-24 13:35:55
【问题描述】:

我不知道如何进行下一个场景。

我有一个 WCF 服务启动并运行,安全性如下:

<binding name="SSLBinding">
   <security mode="Transport">
     <transport clientCredentialType="None"/>
     <!--<message clientCredentialType="UserName"/>-->
   </security>
 </binding>

我能够在 IIS 5.0 中制作一个虚拟证书,因此这个 WCF 可以在 HTTPS 上公开。

最后使用 .Net 客户端我可以与服务通信,如下所示:

private void randomMethod
    {
        //This is necesary, cause the certificate isn´t valid
        ServicePointManager.ServerCertificateValidationCallback =
        new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);            

            RefHTTPS.GestionesServiceClient service = new RefHTTPS.GestionesServiceClient();                

            richTextBox1.Text = service.version();                            
    }

    public static bool IgnoreCertificateErrorHandler(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        return true;
    }

问题:当我尝试在 Java 客户端上执行此操作时,出现异常。

有人已经能够做到这样的事情,我需要一些指导。

我在网上阅读了很多帖子,但没有什么适合我。


编辑(从 OP 的其他内容合并,作为问题发布并标记):

这是完整的配置(它有一个配置标签,但没有显示):

<?xml version="1.0"?>
<system.web>
    <compilation debug="true">          
    </compilation>              
</system.web>  

<system.serviceModel>
    <bindings>

 <binding name="SSLBinding">
   <security mode="Transport">
     <transport clientCredentialType="None"/>
   </security>
 </binding>

</bindings>
<serviceHostingEnvironment>
  <baseAddressPrefixFilters>
    <add prefix="https://x.x.x.x"/>
  </baseAddressPrefixFilters>
</serviceHostingEnvironment>

<services>
   <service behaviorConfiguration="WSGestiones.GestionesServiceBehavior" name="WSGestiones.GestionesService">
      <endpoint address="https://x.x.x.x/GestionesWS/GestionesService.svc"
         binding="basicHttpBinding" bindingConfiguration="SSLBinding" contract="WSGestiones.IGestionesService">            
        <identity>
          <dns value="localhost" />              
         </identity>
      </endpoint>
      <endpoint address="https://x.x.x.x/GestionesWS/GestionesService.svc/mex"
         binding="mexHttpsBinding" contract="IMetadataExchange">
         <identity>
            <dns value="IPADDRESS" />
         </identity>
      </endpoint>
   </service>      
</services>    

<behaviors>
  <serviceBehaviors>
    <behavior name="WSGestiones.GestionesServiceBehavior">
      <serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://x.x.x.x/GestionesWS/GestionesService.svc" />
      <serviceDebug includeExceptionDetailInFaults="true" />          
    </behavior>        

   </serviceBehaviors>
</behaviors>

我能够将证书添加到我的 PC 的受信任列表中,我还添加到了 JDK 或 Java 中的任何位置。

我的一些错误是:

Exception in thread "main" javax.xml.ws.WebServiceException: Cannot find 'https://x.x.x.x/GestionesWS/GestionesService.svc?wsdl' wsdl. Place the resource correctly in the classpath.

HTTP transport error: 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

Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present

Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: com.sun.net.ssl.internal.ssl.DefaultSSLContextImpl)

Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: java.io.IOException: HTTPS hostname wrong:  should be <x.x.x.x>

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: An error occurred when verifying security for the message.

Exception in thread "main" com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 401: Access Denied

每次我遇到错误,在网上搜索并“修复”时,都会出现一个新错误......在我“修复”的第 5 天,我会说“这是一个无限循环”。

所以....我没有尝试修复错误,而是考虑“修复逻辑”。

【问题讨论】:

  • 我的猜测是 Java 不接受证书是有效的。您可能需要以某种方式将其添加到受信任的证书列表中,然后它才能工作。

标签: java wcf iis https certificate


【解决方案1】:

我还尝试通过 Netbeans 连接到具有服务端点的自签名证书的服务器。当我尝试创建一个新的连接对象时,我遇到了这个运行时异常:

javax.xml.ws.WebServiceException: java.io.IOException: HTTPS hostname wrong: should be <hostname as in the certificate>

我终于在Metro's documentation 中找到了关于此异常的部分。不幸的是,他们提供的代码看起来只是一个临时解决方案,但至少看起来你可以解决这个问题。

我通过创建一个静态方法来修改他们提供的代码,我在我的主要方法顶部调用该方法,我总是“验证”我为我的服务连接到的站点:

private static void overrideDefaultHostnameVerifier() {
    //WORKAROUND. TO BE REMOVED.
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
            new javax.net.ssl.HostnameVerifier() {
                @Override
                public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
                    return true;
                }
            });
}

这个问题的真正解决方案似乎是在托管服务端点的服务器上获得一个真正颁发的证书。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多