2012-01-05 70 views
3

我们已经使用Springs HttpInvoker几个星期了,它的功能就像一个魅力。从我的前端(网络)应用程序,我连接到后端的userService这样的:带有https和未签名证书的Spring HTTP调用者

<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceUrl" value="http://${backend.host}/backend-ws/remoting/UserService"/> 
    <property name="serviceInterface" value="com...service.UserService"/> 
</bean> 

的UserService然后很好地注入到我们的前端类。

现在我们将这部署在适当的(WAS7)服务器上,并且需要使用SSL(https)。于是,我改变(的的serviceUrl)的HTTP到HTTPS但后来我得到:

org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [https://pbp-dev.dev.echonet/public/backend-ws/remoting/ParameterHelper]; nested exception is 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 

,因为在服务器上安装证书这是有道理的(在哪里运行)不是由CA签发的。

我们已经有了一些这方面的经验,因为在同一个WAS上有一个web服务正在运行;为此,我们利用CXF,我们已经产生了JKS文件(密钥工具)驻留在客户端应用程序,并设置如下:

<http:conduit name="https://serverurl/.*"> 
<http:tlsClientParameters secureSocketProtocol="SSL" disableCNCheck="false"> 
    <sec:trustManagers> 
     <sec:keyStore type="jks" password="pass123" resource="trust.jks"/> 
    </sec:trustManagers> 
</http:tlsClientParameters> 

我想对HTTP调用,我们需要做的事情相似,但我们不知道如何在调用者中使用这个trust.jks。

我发现的一件事是使用不同的requestExecutor;像这样:

<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceUrl" value="https://${backend.host}/backend-ws/remoting/UserService"/> 
    <property name="serviceInterface" value="com...service.UserService"/> 
    <property name="httpInvokerRequestExecutor"> 
    <bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor" /> 
    </property> 
</bean> 

这之后我不再拿到证书错误,但userService似乎没有要创建自那以后,我得到:如果混合使用,你可以在这里找到(HTTP什么

NoSuchBeanDefinitionException: No matching bean of type [com...service.UserService] found for dependency 
+0

愿这有助于:http://blog.jayway.com/2008/09/30/spring-remoting-with-security-and-ssl/ – Ralph 2012-01-05 11:51:00

+0

@Ralph, tx,我之前已经看过这个博客,但据我了解,它并未完全解决我们的问题(请参阅本博客的最后一篇文章)。 – 2012-01-05 12:36:05

回答

2

://stackoverflow.com/questions/5947162/https-and-self-signed-certificate-issue)来配置HttpClient返回到预先配置的SSLSocketFactory,您可以更改套接字工厂的主机名验证器来接受cerificate,接近此的东西:

xxx.setHostnameVerifier(new HostnameVerifier() { 
    public boolean verify(String hostname, SSLSession session) { println("bypassing ssl cert handshaking as configured for self signed cert."); return true; } 
}); 

根据您的配置,除了使用CommonsHttpInvokerRequestExecutor你还必须配置使用HttpClient的和SSL套接字工厂

我知道这可能并不完全回答你的问题,但它是其他搜索的起点!祝你好运,不要忘记发布最终解决方案。

1

你可以试一下如下:

首先编写自定义类的org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor

package com.myorg.proid.sample; 

import static org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; 

import java.security.KeyManagementException; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableKeyException; 
import java.security.cert.X509Certificate; 

import org.apache.http.client.HttpClient; 
import org.apache.http.conn.scheme.Scheme; 
import org.apache.http.conn.ssl.SSLSocketFactory; 
import org.apache.http.conn.ssl.TrustStrategy; 
import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor; 

/** 
* @author visruth 
* 
*/ 
public class CustomHttpComponentsHttpInvokerRequestExecutor extends 
     HttpComponentsHttpInvokerRequestExecutor { 

    public CustomHttpComponentsHttpInvokerRequestExecutor() { 
     skipSecurityChecking(); 
    } 

    @SuppressWarnings("deprecation") 
    private void skipSecurityChecking() { 

     // HttpClient from super class. 
     HttpClient httpClient = getHttpClient(); 

     TrustStrategy trustStrategy = new TrustStrategy() { 
      @Override 
      public boolean isTrusted(X509Certificate[] certificate, 
        String authType) { 
       return true; 
      } 
     }; 

     try { 
      httpClient 
        .getConnectionManager() 
        .getSchemeRegistry() 
        .register(
          new Scheme("https", 80, new SSLSocketFactory(
            trustStrategy, 
            ALLOW_ALL_HOSTNAME_VERIFIER))); 
     } catch (KeyManagementException e) { 
      e.printStackTrace(); 
     } catch (UnrecoverableKeyException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (KeyStoreException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

,并在您XML文件中引用这个类,而不是​​作为

<bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"> 
    <property name="serviceUrl" value="https://${backend.host}/backend-ws/remoting/UserService"/> 
    <property name="serviceInterface" value="com...service.UserService"/> 
    <property name="httpInvokerRequestExecutor"> 
    <bean class="com.myorg.proid.sample.CustomHttpComponentsHttpInvokerRequestExecutor" /> 
    </property> 
</bean> 
+0

我们不再使用Spring HTTP调用程序,所以我无法验证您的答案,但无论如何+1为努力提供一个老问题的良好答复 – 2015-10-16 15:18:38

+0

@StijnGeukens谢谢。但是,可能知道为什么你不使用HTTP调用者,我的意思是如果你使用任何替代方法呢? – Visruth 2015-10-16 16:57:03

+0

我相信我们切换到粗麻布。 – 2015-10-17 15:37:55