2012-01-05 80 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