package com.infosec.ztpdp.policycenter.component.httpclient;
import java.security.cert.CertificateException;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
/**
*
* <p>
* redis配置
* </p>
*
* <p>
* 版权所有:北京信安世纪科技股份有限公司 (c) 2022
* </p>
*
* @author jlcui
* @date: 2023年8月22日 下午1:09:13
*
*/
@EnableCaching
@AutoConfigureBefore(RestTemplateConfig.class)
@Configuration
public class RestTemplateConfig {
/**http请求等待请求返回时间 单位毫秒 */
@Value("${http.request.read.timeout:20000}")
private Integer readTimeout ;
/**http请求资源等待时间 单位毫秒*/
@Value("${http.request.connection.timeout:10000}")
private Integer connectionTimeout ;
/**
* <p>
* Description: http请求方式
* </p>
* @param restTemplateBuilder
* @return
*
* @author Tianzy
*
* 2020年5月18日 下午1:53:53
*
*/
@Bean("restTemplate")
public RestTemplate restTemplate(){
RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(
MediaType.TEXT_HTML,
MediaType.TEXT_PLAIN));
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
return restTemplate;
}
@Bean
public HttpClient httpClientPool() {
SSLConnectionSocketFactory sslsf = null;
try {
sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySsl(),
// 指定TLS版本
null,
// 指定算法
null,
// 取消域名验证
new HostnameVerifier() {
@Override
public boolean verify(String string, SSLSession ssls) {
return true;
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslsf == null?SSLConnectionSocketFactory.getSocketFactory():sslsf)
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
//设置整个连接池最大连接数 根据自己的场景决定
connectionManager.setMaxTotal(200);
//路由是对maxTotal的细分
connectionManager.setDefaultMaxPerRoute(100);
RequestConfig requestConfig = RequestConfig.custom()
//服务器返回数据(response)的时间,超过该时间抛出read timeout
.setSocketTimeout(readTimeout)
//连接上服务器(握手成功)的时间,超出该时间抛出connect timeout
.setConnectTimeout(connectionTimeout)
//从连接池中获取连接的超时时间,超过该时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
.setConnectionRequestTimeout(1000)
.build();
return HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(connectionManager)
.build();
}
@PostConstruct
private void init() {
HttpClientUtils.httpRestTemplate = restTemplate() ;
}
/**
* 跳过证书效验的sslcontext
*
* @return
* @throws Exception
*/
private static SSLContext createIgnoreVerifySsl() throws Exception {
SSLContext sc = SSLContext.getInstance("TLS");
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sc.init(null, new TrustManager[] { trustManager }, null);
return sc;
}
}
package com.infosec.ztpdp.policycenter.component.httpclient;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import com.alibaba.fastjson.JSONObject;
import com.infosec.ztpdp.policycenter.common.jsonresult.JsonResult;
import com.infosec.ztpdp.policycenter.common.util.Const;
import com.infosec.ztpdp.policycenter.common.util.SymbolConst;
import com.infosec.ztpdp.policycenter.common.util.deciphering.EncryptionFactory;
import com.infosec.ztpdp.policycenter.module.system.confignetauthdatasource.entity.ConfigNetauthDataSourceBean;
import com.infosec.ztpdp.policycenter.module.system.confignetauthdatasource.service.ConfigNetauthDataSourceService;
/**
* <p>
* 策略中心调用iam工具类
* </p>
*
* <p>
* 版权所有:北京信安世纪科技股份有限公司 (c) 2019
* </p>
*
* @author Tianzy
*
* 2023年10月9日 上午10:22:25
*
*/
@Component
public class IamInterfaceClient {
@Autowired
private RestTemplate restTemplate;
@Autowired
private ConfigNetauthDataSourceService iamService ;
private final String APPID_STR = "appid" ;
private final String TIMESTAMP_STR = "timestamp" ;
private final String TOKEN_STR = "token" ;
public final Integer ADMIN_SERVER = 1 ;
public final Integer SSO_SERVER = 2 ;
/**
* <p>
* Description: 请求iam接口,获取json格式返回值
* </p>
* @param serverType 服务类型 1 admin 2 sso
* @param url
* @param paramMap 请求参数
* @param method HttpMethod.GET HttpMethod.POST
*
* @author Tianzy
*
* 2023年9月28日 下午5:12:54
*
*/
public <T> JsonResult<T> getJsonResult(Integer serverType,String subUrl,Map<String, Object> paramMap,Integer requestType)
throws Exception{
ConfigNetauthDataSourceBean netauthVO = iamService.findOpenIamSource() ;
String ssoUrl = new StringBuffer().append(netauthVO.getSsoProtocol()).append(SymbolConst.COLON).append(SymbolConst.DOUBLE_SLASH)
.append(netauthVO.getSsoIpAddress()).append(SymbolConst.COLON).append(netauthVO.getSsoPort()).toString() ;
String adminUrl = new StringBuffer().append(netauthVO.getAdminProtocol()).append(SymbolConst.COLON).append(SymbolConst.DOUBLE_SLASH)
.append(netauthVO.getAdminIpAddress()).append(SymbolConst.COLON).append(netauthVO.getAdminPort()).toString() ;
String appId = netauthVO.getAppId() ;
String sharekey = netauthVO.getShareKey() ;
// 设置Http Header
HttpHeaders headers = new HttpHeaders();
headers.add(APPID_STR, appId);
String thisTimestamp = String.valueOf(System.currentTimeMillis()) ;
headers.add(TIMESTAMP_STR, thisTimestamp);
headers.add(TOKEN_STR,EncryptionFactory.encrypt(EncryptionFactory.ALG_SHA256, sharekey + appId + thisTimestamp) );
// 设置返回媒体数据类型
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(headers);
String url = (ADMIN_SERVER == serverType ? adminUrl : ssoUrl) + subUrl ;
ResponseEntity<JSONObject> iamResult = null ;
if(Const.CONST_INTEGER_1 == requestType) {
if(!CollectionUtils.isEmpty(paramMap)) {
StringBuffer urlAndParam = new StringBuffer(url).append(SymbolConst.QUESTION) ;
for(String key : paramMap.keySet()) {
urlAndParam.append(SymbolConst.SINGLE_ALSO).append(key).append(SymbolConst.BE_EQUAL_TO).append(paramMap.get(key));
}
url = urlAndParam.toString().replaceFirst(SymbolConst.SINGLE_ALSO, SymbolConst.NULL_STR) ;
}
iamResult = restTemplate.exchange(url,HttpMethod.GET,httpEntity,JSONObject.class) ;
}else {
LinkedMultiValueMap<String, Object> paramLinkMap = new LinkedMultiValueMap<>();
if(!CollectionUtils.isEmpty(paramMap)) {
for(String key : paramMap.keySet()) {
paramLinkMap.add(key, paramMap.get(key));
}
}
httpEntity = new HttpEntity<>(paramLinkMap,headers);
iamResult = restTemplate.exchange(url,HttpMethod.POST,httpEntity,JSONObject.class) ;
}
JSONObject jsonResult = iamResult.getBody();
@SuppressWarnings("unchecked")
JsonResult<T> result = JSONObject.parseObject(jsonResult.toJSONString(), JsonResult.class) ;
return result ;
}
}
package com.infosec.ztpdp.policycenter.component.httpclient;
import org.springframework.web.client.RestTemplate;
/**
* <p>
* 调用Http接口工具类
* 使用的为RestTemplate。
* </p>
*
* <p>
* 版权所有:北京信安世纪科技股份有限公司 (c) 2019
* </p>
*
* @author Tianzy
*
* 2020年9月10日 上午11:30:24
*
*/
public class HttpClientUtils {
/** http */
public static RestTemplate httpRestTemplate ;
/**
* <p>
* Description: 获取Http接口调用 客户端
* </p>
* @return
*
* @author Tianzy
*
* 2020年9月15日 下午6:01:55
*
*/
public static RestTemplate gethTttpRestTemplate() {
return httpRestTemplate ;
}
}