HttpInvoker支持不需要证书的HTTPS

来源:互联网 发布:淘宝网羊毛衫 编辑:程序博客网 时间:2024/06/06 05:45
【问题】
遇到内部管理非常严格的客户可能存在一套内部系统的部署规范,例如只支持HTTPS协议不支持HTTP,如果系统多出采用HttpInvoker,而此处的配置大多不能直接支持HTTPS。我们可以建议客户同时开放HTTP和HTTPS,对外只开放HTTPS端口,此时物理服务器内部的应用可以使用HTTP协议进行HttpInvoker交互,但如果是分布式部署呢?
 
   【解决办法】
1.  大多的配置如下(很多程序都采用如下配置方式),此时只能支持HTTP协议,不支持HTTPS:
[java] view plaincopyprint?
  1. <bean id="remoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">  
  2.             <!--  远程服务的url-->  
  3.             <property name="serviceUrl" value="${tt.server}/remoteService.remoting" />  
  4.             <!--  远程服务所实现的接口-->  
  5.         <property name="serviceInterface" value="org.kevin.SimpleService" />  
  6.         </bean>  

  2.  可以调整为如下,使其同时支持HTTP和HTTPS:           
[java] view plaincopyprint?
  1. <SPAN style="WHITE-SPACE: pre">     </SPAN><bean id="remoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">  
  2.             <!--  远程服务的url-->  
  3.                         <property name="serviceUrl" value="${tt.server}/remoteService.remoting" />  
  4.                         <!--  远程服务所实现的接口-->  
  5.                         <property name="serviceInterface" value="org.kevin.SimpleService" />  
  6.                         <property name="httpInvokerRequestExecutor">  
  7.                             <bean class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor"></bean>  
  8.                         </property>  
  9.             </bean>  
                  但问题是又来了,这个httpInvokerRequestExecutor使用的是HttpClient,而这个家伙要求你必须配置证书文件(配置方法很复杂,还要考虑证书过期更新问题)。
 
3. 怎么办!?改写一下CommonsHttpInvokerRequestExecutor ,让他即支持HTTPS同时还不校验证书(有点安全隐患,不过用该可以接收),于是采用如下配置:
[java] view plaincopyprint?
  1. <bean id="remoteService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">  
  2.         <!--  远程服务的url-->  
  3.         <property name="serviceUrl" value="${tt.server}/remoteService.remoting" />  
  4.         <!--  远程服务所实现的接口-->  
  5.         <property name="serviceInterface" value="org.kevin.SimpleService" />  
  6.         <property name="httpInvokerRequestExecutor">  
  7.                 <bean class="org.kevin.KevinCommonsHttpInvokerRequestExecutor"></bean>  
  8.         </property>  
  9.   </bean>  

【示例代码】
[java] view plaincopyprint?
  1. package org.kevin;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.InetAddress;  
  5. import java.net.Socket;  
  6. import java.net.UnknownHostException;  
  7. import java.security.cert.CertificateException;  
  8. import java.security.cert.X509Certificate;  
  9.   
  10. import javax.net.ssl.SSLContext;  
  11. import javax.net.ssl.TrustManager;  
  12. import javax.net.ssl.X509TrustManager;  
  13.   
  14. import org.apache.commons.httpclient.ConnectTimeoutException;  
  15. import org.apache.commons.httpclient.HttpClientError;  
  16. import org.apache.commons.httpclient.params.HttpConnectionParams;  
  17. import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;  
  18. import org.apache.commons.httpclient.protocol.Protocol;  
  19. import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;  
  20. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;  
  21. import org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor;  
  22.   
  23. /** 
  24.  * <p> 
  25.  * Title: HttpInvoker的自定义httpInvokerRequestExecutor实现 
  26.  * </p> 
  27.  *  
  28.  * <p> 
  29.  * Description: 支持HTTP和HTTPS,同时HTTPS不进行证书的校验 
  30.  * </p> 
  31.  *  
  32.  * <p> 
  33.  * Company: 北京九恒星科技股份有限公司 
  34.  * </p> 
  35.  *  
  36.  * @author li.wenkai 
  37.  *  
  38.  * @since:2011-10-18 下午03:37:03 
  39.  *  
  40.  */  
  41. public class KevinCommonsHttpInvokerRequestExecutor extends CommonsHttpInvokerRequestExecutor {  
  42.   
  43.     static {  
  44.         ProtocolSocketFactory fcty = new MySecureProtocolSocketFactory();  
  45.         Protocol.registerProtocol("https"new Protocol("https", fcty, 443));  
  46.     }  
  47. }  
  48.   
  49. class MyX509TrustManager implements X509TrustManager {  
  50.   
  51.     /* 
  52.      * (non-Javadoc) 
  53.      *  
  54.      * @see 
  55.      * javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert. 
  56.      * X509Certificate[], java.lang.String) 
  57.      */  
  58.     public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {  
  59.   
  60.     }  
  61.   
  62.     /* 
  63.      * (non-Javadoc) 
  64.      *  
  65.      * @see 
  66.      * javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert. 
  67.      * X509Certificate[], java.lang.String) 
  68.      */  
  69.     public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {  
  70.   
  71.     }  
  72.   
  73.     /* 
  74.      * (non-Javadoc) 
  75.      *  
  76.      * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() 
  77.      */  
  78.     public X509Certificate[] getAcceptedIssuers() {  
  79.         return null;  
  80.     }  
  81.   
  82.     public boolean isClientTrusted(X509Certificate[] arg0) {  
  83.         return false;  
  84.     }  
  85.   
  86.     public boolean isServerTrusted(X509Certificate[] arg0) {  
  87.         return false;  
  88.     }  
  89.   
  90. }  
  91.   
  92. class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {  
  93.   
  94.     private SSLContext sslContext = null;  
  95.   
  96.     /** 
  97.      * Constructor for MySecureProtocolSocketFactory. 
  98.      */  
  99.     public MySecureProtocolSocketFactory() {  
  100.     }  
  101.   
  102.     /** 
  103.      *  
  104.      * @return 
  105.      */  
  106.     private static SSLContext createEasySSLContext() {  
  107.         try {  
  108.             SSLContext context = SSLContext.getInstance("SSL");  
  109.             context.init(nullnew TrustManager[] { new MyX509TrustManager() }, null);  
  110.             return context;  
  111.         } catch (Exception e) {  
  112.             throw new HttpClientError(e.toString());  
  113.         }  
  114.     }  
  115.   
  116.     /** 
  117.      *  
  118.      * @return 
  119.      */  
  120.     private SSLContext getSSLContext() {  
  121.         if (this.sslContext == null) {  
  122.             this.sslContext = createEasySSLContext();  
  123.         }  
  124.         return this.sslContext;  
  125.     }  
  126.   
  127.     /* 
  128.      * (non-Javadoc) 
  129.      *  
  130.      * @see 
  131.      * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket 
  132.      * (java.lang.String, int, java.net.InetAddress, int) 
  133.      */  
  134.     public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,  
  135.             UnknownHostException {  
  136.   
  137.         return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);  
  138.     }  
  139.   
  140.     /* 
  141.      * (non-Javadoc) 
  142.      *  
  143.      * @see 
  144.      * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket 
  145.      * (java.lang.String, int, java.net.InetAddress, int, 
  146.      * org.apache.commons.httpclient.params.HttpConnectionParams) 
  147.      */  
  148.     public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort,  
  149.             final HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {  
  150.         if (params == null) {  
  151.             throw new IllegalArgumentException("Parameters may not be null");  
  152.         }  
  153.         int timeout = params.getConnectionTimeout();  
  154.         if (timeout == 0) {  
  155.             return createSocket(host, port, localAddress, localPort);  
  156.         } else {  
  157.             return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);  
  158.         }  
  159.     }  
  160.   
  161.     /* 
  162.      * (non-Javadoc) 
  163.      *  
  164.      * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) 
  165.      */  
  166.     public Socket createSocket(String host, int port) throws IOException, UnknownHostException {  
  167.         return getSSLContext().getSocketFactory().createSocket(host, port);  
  168.     }  
  169.   
  170.     /* 
  171.      * (non-Javadoc) 
  172.      *  
  173.      * @see 
  174.      * SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String 
  175.      * ,int,boolean) 
  176.      */  
  177.     public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,  
  178.             UnknownHostException {  
  179.         return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);  
  180.     }  
  181. }  

 
原创粉丝点击