【问题标题】:Spring HTTP invoker with https and unsigned certificate带有 https 和未签名证书的 Spring HTTP 调用程序
【发布时间】:2012-02-03 05:08:26
【问题描述】:

我们已经使用 Springs HttpInvoker 几个星期了,它就像一个魅力。从我的前端(网络)应用程序中,我连接到后端的 userService,如下所示:

<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

这是有道理的,因为安装在服务器(WAS 运行的地方)上的证书没有由 CA 签名。

我们已经有了一些经验,因为在同一个 WAS 上运行了一个 web 服务;为此,我们使用 cxf 并生成了一个 jks 文件(使用 keytool),该文件位于客户端应用程序中,设置如下:

<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 Invoker,我们需要做一些类似的事情,但我们不知道如何在调用者中使用这个 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:

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

【问题讨论】:

  • 希望对您有帮助:blog.jayway.com/2008/09/30/…
  • @Ralph,tx,我之前已经看过这个博客,但据我了解,它并没有完全解决我们的问题(请参阅此博客中的最​​后一篇文章)。

标签: spring ssl https ssl-certificate httpinvoker


【解决方案1】:

如果您混合您可以在此处找到的内容 (http://stackoverflow.com/questions/5947162/https-and-self-signed-certificate-issue) 来配置返回的 HttpClient 以具有预配置的 SSLSocketFactory,您可以更改套接字工厂的主机名验证器以接受证书,类似于此:

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 Socket 工厂

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

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    先写一个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 文件中引用此类,而不是 org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor as

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

    【讨论】:

    • 我们不再使用 Spring HTTP 调用程序,因此我无法验证您的答案,但无论如何 +1 是为了努力为一个老问题提供良好的答复
    • @StijnGeukens 谢谢。但是,可能知道您为什么不使用 HTTP 调用程序,我的意思是您是否使用任何替代方法?
    • 我相信我们改用了粗麻布。
    • 可以为最新版本的 Apache HttpClient 更新实现。请参阅:stackoverflow.com/questions/19517538/…
    猜你喜欢
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 2020-04-24
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多