com.alibaba.csb.ws.sdk.WSClientSDK Maven / Gradle / Ivy
package com.alibaba.csb.ws.sdk;
import com.alibaba.csb.sdk.CsbSDKConstants;
import com.alibaba.csb.sdk.security.SignUtil;
import com.alibaba.csb.ws.sdk.internal.AxisStubDynamicProxyHandler;
import com.alibaba.csb.ws.sdk.internal.BindingDynamicProxyHandler;
import org.apache.axis.client.Stub;
import javax.net.ssl.*;
import javax.xml.ws.BindingProvider;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
/**
* Bind accessKey, secretKey into the WS client caller (i.e. Dispath, Proxy)
*
*
* The tool adds the security headers (as http headers) internally when sending a soap
* request, the headers include the following:
*
*
* {@code
* _api_name:api_name
* _api_version:api_version
* _api_access_key:abc //the access key
* _api_timestamp:1464603102715 //the current timestamp of invoker machine
* _api_fingerprint:invoke // the invocation web service method
* _api_signature:FLHVBMMjaxMPUHy+2VCGPvRNcao= //the signature string calculated with ak, timestamp, fingerprint and sk
* }
*
*
*
* {@code
* Usage:
*
* //obtain dispatch or proxy
* Dispatch patch = ...
*
*
* //bind the dispatch with ak/sk
* WSParams params = WSParams.create();
* params.accessKey("xxxxx");
* params.secretKey("xxxxx");
* params.api("xxxxx");
* params.version("xxxxx");
* dispatch = WSClientSDK.bind(dispatch, params);
*
* //invoke the methods with the returned dispatch
* ret = dispatch.invoke(...);
*
* }
*
*
* @author Alibaba Middleware CSB Team
* @author liaotian.wq
* @since 2016
*/
public class WSClientSDK {
private static boolean warmupFlag = false;
private static final String BOUND_HANDLER_KEY = "__DynamicProxyHandler";
public static final boolean PRINT_SIGNINFO = Boolean.getBoolean("WSClientSDK.print.signinfo");
private static AtomicReference BIZ_ID_KEY = new AtomicReference();
static {
disableSslVerification();
}
private static void disableSslVerification() {
try {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
}
/**
* 加载HttpSDK所需要的类 (如,签名相关的)
*
* 注意:这是一个高时间代价的启动方法,建议在整个JVM范围内,在使用HttpCaller调用具体的服务前,调用且只调用一次
*/
public static synchronized void warmup() {
if (warmupFlag) {
return;
}
SignUtil.warmup();
warmupFlag = true;
}
/**
* init bizIdKey
*
* @param bizIdKey
*/
public static void bizIdKey(String bizIdKey) {
BIZ_ID_KEY.compareAndSet(null, bizIdKey);
}
/**
* get bizIdkey
*
* @return
*/
public static String bizIdKey() {
String bizIdKey = BIZ_ID_KEY.get();
return bizIdKey == null ? CsbSDKConstants.BIZID_KEY : bizIdKey;
}
/**
* 给proxy/dispath 绑定ak/sk安全对
*
* @param proxy 客户端proxy或者dispatch
* @param accessKey accessKey
* @param secretKey secretKey
* @return 封装了accessKey和secretKey的proxy或者dispath, 调用逻辑要使用这个返回进行WS方法调用
* @throws WSClientException
* @deprecated 使用 bind(T proxy, WSParams params)
*/
public static T bind(T proxy, String accessKey, String secretKey) throws WSClientException {
return bind(proxy, accessKey, secretKey, null, null);
}
/**
* 把签名和调用相关的参数绑定到ws客户端,以便调用时在SOAP请求中生成签名验证相关的http headers
*
* @param proxy
* @param params
* @param
* @return
* @throws WSClientException
*/
public static T bind(T proxy, WSParams params) throws WSClientException {
validateProxy(proxy);
BindingDynamicProxyHandler handler = getHandler((BindingProvider) proxy);
handler.setParams(params);
return handler.bind(proxy);
}
public static Object bind(T proxy, WSParams params) throws WSClientException {
AxisStubDynamicProxyHandler handler = new AxisStubDynamicProxyHandler();
handler.setParams(params);
return handler.bind(proxy);
}
/**
* @param proxy
* @param accessKey
* @param secretKey
* @param apiName
* @param apiVersion
* @param printHeaders
* @param
* @return
* @throws WSClientException
* @deprecated 使用 bind(T proxy, WSParams params)
*/
public static T bind(T proxy, String accessKey, String secretKey, String apiName, String apiVersion, boolean printHeaders) throws WSClientException {
validateProxy(proxy);
BindingDynamicProxyHandler handler = getHandler((BindingProvider) proxy);
WSParams params = WSParams.create().accessKey(accessKey).secretKey(secretKey).api(apiName).version(apiVersion).debug(printHeaders);
handler.setParams(params);
return handler.bind(proxy);
}
/**
* 给proxy/dispath 绑定ak/sk安全对,及要调用的apiName和apiVersion
*
* @param proxy 客户端proxy或者dispatch
* @param accessKey accessKey
* @param secretKey secretKey
* @param apiName 服务名
* @param apiVersion 服务版本
* @return 封装了accessKey和secretKey的proxy或者dispath, 调用逻辑要使用这个返回进行WS方法调用
* @throws WSClientException
* @deprecated 使用 bind(T proxy, WSParams params)
*/
public static T bind(T proxy, String accessKey, String secretKey, String apiName, String apiVersion) throws WSClientException {
return bind(proxy, accessKey, secretKey, apiName, apiVersion, false);
}
/**
* 设置直接从服务端返回预定义的MockResponse
*
* @param proxy 客户端proxy或者dispatch
* @param isMock 是否使用mock
* @return 封装了mock标志的proxy或者dispath
* @throws WSClientException
* @deprecated 使用 bind(T proxy, WSParams params) 使用WSParams来设置是否为mockResponse
*/
public static T setResponseMock(T proxy, boolean isMock) throws WSClientException {
validateProxy(proxy);
BindingDynamicProxyHandler handler = getHandler((BindingProvider) proxy);
handler.setMock(isMock);
return handler.bind(proxy);
}
private static BindingDynamicProxyHandler getHandler(BindingProvider bp) {
BindingDynamicProxyHandler handler = (BindingDynamicProxyHandler) bp.getRequestContext().get(BOUND_HANDLER_KEY);
if (handler != null) {
return handler;
}
handler = new BindingDynamicProxyHandler();
//hold the reference of the handler, make they have the same lifecycle
bp.getRequestContext().put(BOUND_HANDLER_KEY, handler);
return handler;
}
private static void validateProxy(Object proxy) throws WSClientException {
if (proxy == null) {
throw new WSClientException("proxy parameter is null");
}
if (!(proxy instanceof BindingProvider)) {
throw new WSClientException("proxy is not a legal soap client");
}
}
public static Map genExtHeader(String fingerStr) {
Map extSignHeaderMap = new HashMap();
if (fingerStr != null) {
extSignHeaderMap.put(CsbSDKConstants.HEADER_FINGERPRINT, fingerStr);
}
return extSignHeaderMap;
}
/**
* 生成签名相关的HTTP所有请求头
*
* @param params
* @return
*/
public static Map generateSignHeaders(WSParams params) {
Map extSignHeaderMap = genExtHeader(params.getFingerPrinter());
Map requestHeaders = SignUtil.newParamsMap(null, params.getApi(), params.getVersion()
, params.getAk(), params.getSk(), params.isTimestamp(), params.isNonce(), extSignHeaderMap
, null, params.getSignImpl(), params.getVerifySignImpl(), params.getSignAlgothrim());
if (params.isMockRequest()) {
requestHeaders.put(CsbSDKConstants.HEADER_MOCK, "true");
}
return requestHeaders;
}
}