Post、Get请求Https,SSL证书的问题
最近在和第三方厂家进行数据对接,需要统一认证走单点登录,就涉及到调用统一认证平台的接口,由于平台提供的接口为https,导致在请求的时候一直会因为SSL证书的校验出错,因此需要跳过SSL证书的校验,步骤如下
第一步,新建一个类
代码如下:
public class TrustAllTrustManager implements TrustManager, X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return;
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return;
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
第二步,在建立URLConnection之前就进行SSL证书的忽略,写一个方法
代码如下
private void skipSslValidation() throws NoSuchAlgorithmException, KeyManagementException {
//默认使用本地
HostnameVerifier hv = new HostnameVerifier() {
@Override
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
TrustManager[] trustAllCerts = {new TrustAllTrustManager()};
SSLContext sc = SSLContext.getInstance("SSL");
SSLSessionContext sslsc = sc.getServerSessionContext();
sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 激活主机认证
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
第三步,GET请求调用
代码如下
private String getUserInfo(String userUrl) {
String returnStr = null;
try {
//解决SSL验证的问题
skipSslValidation();
URL url = new URL(userUrl);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
InputStream inStream = con.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] b = outStream.toByteArray();
outStream.close();
inStream.close();
returnStr = new String(b,"utf-8");
} catch (Exception e) {
logger.error(AuthExceptionMsg.GET_USER_INFO_ERROR.getMsg(),e.getMessage());
throw new ServiceException(AuthExceptionMsg.GET_USER_INFO_ERROR);
}
return returnStr;
}
第四步,Post请求调用
刚好本次调用第三方接口时,对方接受的传参类型是application/x-www-form-urlencoded,平常写application/json比较多,发现这种方式还是有点区别,传参用key=value的方式,并且参数之间用&拼接,有点类似GET请求,因此一起记录下来
代码如下
private String getCodeToToken(AuthRequestForm authRequestForm) {
String result = "";
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("grant_type",ssoLoginConfig.getGrantType());
hashMap.put("client_id",ssoLoginConfig.getClientId());
hashMap.put("client_secret",ssoLoginConfig.getClientSecret());
hashMap.put("redirect_uri",authRequestForm.getRedirectUri());
hashMap.put("code",authRequestForm.getCode());
StringBuffer params = new StringBuffer();
for (HashMap.Entry<String, Object> e : hashMap.entrySet()) {
params.append(e.getKey());
params.append("=");
params.append(e.getValue());
params.append("&");
}
URL reqURL;
try {
//跳过SSL验证
skipSslValidation();
reqURL = new URL(ssoLoginConfig.tokenUrl);
HttpURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection();
httpsConn.setDoOutput(true);
httpsConn.setRequestMethod("POST");
httpsConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
httpsConn.setRequestProperty("Accept-Charset", "utf-8");
httpsConn.setRequestProperty("contentType", "utf-8");
httpsConn.setRequestProperty("Content-Length", params.length() + "");
OutputStreamWriter out = new OutputStreamWriter(httpsConn.getOutputStream(),"utf-8");
out.write(params.toString());
out.flush();
out.close();
//取得该连接的输入流,以读取响应内容
InputStreamReader inputStreamReader = new InputStreamReader(httpsConn.getInputStream(),"utf-8");
int respInt = inputStreamReader.read();
while(respInt != -1) {
result = result + (char) respInt;
respInt = inputStreamReader.read();
}
} catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
logger.error(AuthExceptionMsg.CODE_TO_TOKEN_ERROR.getMsg(), e.getMessage());
throw new ServiceException(AuthExceptionMsg.CODE_TO_TOKEN_ERROR);
}
if (StringUtils.isEmpty(result)){
return null;
}else {
return result;
}
}
以上就是所有记录。