1. 程式人生 > >Cxf和Axis使用https進行通訊的筆記示例

Cxf和Axis使用https進行通訊的筆記示例

1. Cxf使用https進行通訊

1.1動態生成ws代理的工具類如下:

import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;
import javax.security.cert.X509Certificate;


public class CXFUtil {
    protected static final Logger LOG = LoggerFactory.getLogger(CXFUtil.class);
    /**
     * 證書信任管理
     */
    private static X509TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            //不檢查
        }

        public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
            //不檢查
        }
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException {
            //不檢查
        }

        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException {
            //不檢查
        }
    };

    /**
     * 建立webservice代理
     *
     * @param clazz
     * @param wsdl
     * @return
     */
    public static <T> T lookUp(Class<T> clazz, String wsdl) {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        // 設定介面類
        factory.setServiceClass(clazz);
        factory.setAddress(wsdl);
        // 許可權設定攔截器,會在請求發出時將token設定到header中
        // 新增許可權設定攔截器
        return (T) factory.create();
    }


    /**
     * 在WebService客戶端請求https時,忽略檢查服務端證書是否是信任的
     *
     * @param obj
     * @author dongming 2017年3月9日14:58:05
     */
    public static void configureSSLOnTheClient(Object obj) {
        Client client = ClientProxy.getClient(obj);
        HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
        try {
            TLSClientParameters tlsParams = new TLSClientParameters();
            tlsParams.setDisableCNCheck(true);
            tlsParams.setTrustManagers(new TrustManager[]{tm});
            httpConduit.setTlsClientParameters(tlsParams);
            LOG.info("Configure SSL On The Client Success");
        } catch (Exception e) {
            LOG.error("Set Trust Managers Error", e);
        }
    }
}

1.2 使用示例如下:

// IVMSWebService 是使用CXF工具生成的ws類的介面,ip也即wsdl地址
IVMSWebService service = CXFUtil.lookUp(IVMSWebService.class, ip); 

//忽略服務端證書檢查 
CXFUtil.configureSSLOnTheClient(service);

2.1 AXIS使用https通訊必須的工具類如下:

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

public class SSLIgnoreErrorProtocolSocketFactory implements ProtocolSocketFactory{

	private SSLContext sslcontext = null;
	
	/**
	* 不進行證明書的驗證
	* 
	* @return
	*/
	private static SSLContext createEasySSLContext() {
		try {
			SSLContext context = SSLContext.getInstance("SSL");
			context.init(null, new TrustManager[] { new X509TrustManager() {
				public void checkClientTrusted(X509Certificate[] arg0,
						String arg1) throws CertificateException {
				}
		
				public void checkServerTrusted(X509Certificate[] arg0,
						String arg1) throws CertificateException {
				}
		
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			} }, null);
			return context;
		} catch (Exception e) {
			throw new HttpClientError(e.toString());
		}
	}
	
	private SSLContext getSSLContext() {
		if (this.sslcontext == null) {
			this.sslcontext = createEasySSLContext();
		}
		return this.sslcontext;
	}
	
	@Override
	public Socket createSocket(String host, int port) throws IOException,
		UnknownHostException {
	    return getSSLContext().getSocketFactory().createSocket(host, port);
	}
	
	@Override
	public Socket createSocket(String host, int port, InetAddress clientHost,
		int clientPort) throws IOException, UnknownHostException {
	    return getSSLContext().getSocketFactory().createSocket(host, port,
			clientHost, clientPort);
	}
	
	@Override
	public Socket createSocket(String host, int port, InetAddress localAddress,
		int localPort, HttpConnectionParams params) throws IOException,
		UnknownHostException, ConnectTimeoutException {
		if (params == null) {
			throw new IllegalArgumentException("Parameters may not be null");
		}
		int timeout = params.getConnectionTimeout();
		SocketFactory socketfactory = getSSLContext().getSocketFactory();
		if (timeout == 0) {
			return socketfactory.createSocket(host, port, localAddress,
					localPort);
		} else {
			Socket socket = socketfactory.createSocket();
			SocketAddress localaddr = new InetSocketAddress(localAddress,
					localPort);
			SocketAddress remoteaddr = new InetSocketAddress(host, port);
			socket.bind(localaddr);
			socket.connect(remoteaddr, timeout);
			return socket;
		}
    }
}

2.2 axis使用https通訊示例

//stub是使用命令WSDL2Java -uri http://10.66.71.127:28010/?wsdl  -p com.lhever.core  -d adb -s -o build\client 生成的ws代理類
 IVMSWebServiceImpServiceStub stub = new IVMSWebServiceImpServiceStub(ip);//ip也即wsdl地址
 if (ip.contains("https")) { //使用https通訊的邏輯在這裡
                SSLIgnoreErrorProtocolSocketFactory socketfactory = new SSLIgnoreErrorProtocolSocketFactory();
				
				//Protocol類似包org.apache.commons.httpclient.protocol
                Protocol protocol = new Protocol("https", socketfactory, 18080); //18080也即wsdl中的埠號,為了便於理解程式碼,此處寫死
                stub._getServiceClient().getOptions().setProperty("CUSTOM_PROTOCOL_HANDLER", protocol);
            }
stub.submitJob(); // submitJob是該wsdl釋出的一個服務