Интерфейс вызова HttpClient использует и вводит проверку подписи

иллюстрировать

HttpClient — это широко используемая клиентская библиотека Java HTTP, которую можно использовать для отправки HTTP-запросов и получения ответов. Как правило, при подключении к другим сервисным интерфейсам необходимо внедрять механизм проверки подписи, в данной статье используется пример вызова интерфейса и внедрения проверки подписи на основе HttpClient.

Ввести этапы проверки подписи:

    1. Определите алгоритм подписи и алгоритм проверки подписи: выберите соответствующий алгоритм подписи и алгоритм проверки подписи в соответствии с конкретными потребностями бизнеса. Обычно используемые алгоритмы подписи включают HMAC-SHA1, HMAC-SHA256 и т. д. Обычно используемые алгоритмы проверки подписи включают RSA, DSA и т. д.
    1. Добавить информацию о подписи в запрос: перед отправкой запроса параметры запроса должны быть подписаны в соответствии с выбранным алгоритмом подписи, а результат подписи добавляется в заголовок запроса или параметры запроса. Информация о подписи может быть закодирована в Base64 или другими способами.
    1. Проверка подписи при получении ответа: после получения ответа необходимо получить информацию о подписи из заголовка ответа или параметров ответа и использовать выбранный алгоритм проверки подписи для проверки результата ответа. Если проверка подписи прошла успешно, результат ответа можно считать достоверным, если проверка подписи не удалась, результат ответа следует отбросить или выполнить другую обработку.

Импорт зависимостей

	<dependency>
	    <groupId>org.apache.httpcomponents</groupId>
	    <artifactId>httpclient</artifactId>
	    <version>4.5.12</version>
	</dependency>
	<dependency>
	    <groupId>org.apache.commons</groupId>
	    <artifactId>commons-lang3</artifactId>
	    <version>3.9</version>
	</dependency>
	<dependency>
	    <groupId>com.google.code.gson</groupId>
	    <artifactId>gson</artifactId>
	    <version>2.8.6</version>
	</dependency>

или

    compile 'com.google.code.gson:gson:2.8.6'
    compile 'org.apache.httpcomponents:httpclient:4.5.12'
    compile 'org.apache.commons:commons-lang3:3.9'

Получить запрос

import kl.idaas.util.TokenUtils;
import com.google.gson.Gson;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.math.BigDecimal;
import java.net.URI;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * 拉取接口调用示例代码
 */
public class PullDataDemo {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //接口地址,详见接口定义
        String restSever = "http://xxx.xxxx.com/service/pull/orgs";
        // 标识
        String appKey = "xxxxxxxxxxxxxxxxxxx";
        // 系统签发给应用对接的密钥
        String pwd = "xxxxxxxxxxxxxxxxxxx";
        // 时间戳
        Long ts = Calendar.getInstance().getTime().getTime();
        // 随机数
        String once = RandomStringUtils.randomAlphanumeric(32);
        String signMethod = "SHA-256";

        // 创建HttpClient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, ts, once, signMethod);

        //循环拉取,直至数据拉取完毕
        //首次调用时填写0,之后调用填写系统已持久化存储的数据中最大的syncSequence
        Long syncSequence = 0L;
        while (true) {
    
    
            String getQueryParam = "syncSequence="+syncSequence;
            String getFullUrl = restSever + "?" + getQueryParam;
            HttpGet httpGet = new HttpGet(getFullUrl);
            String getAllParamUrl = commonParamUrl + "&" + getQueryParam;
            System.out.println("请求参数:" + getAllParamUrl);
            // 签名数据
            String signData = TokenUtils.getSignature(pwd, getAllParamUrl);
            // 添加header参数 appCode、timestamp、 signatureNonce、signature
            httpGet.addHeader("appKey", appKey);
            httpGet.addHeader("ts", ts.toString());
            httpGet.addHeader("once", once);
            httpGet.addHeader("signMethod", signMethod);
            System.out.println("once:" + once);
            httpGet.addHeader("signData", signData);
            System.out.println("headers:" + Arrays.toString(httpGet.getAllHeaders()));

            String urlStr = httpGet.getURI().toString();

            // 公共参数URL
            System.out.println("commonParamter:" + urlStr);

            if (StringUtils.endsWith(urlStr, "/")) {
    
    
                urlStr = StringUtils.removeEnd(urlStr, "/");
            }

            httpGet.setURI(new URI(urlStr));
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000).setSocketTimeout(5000).build();
            httpGet.setConfig(requestConfig);
            System.out.println("urlStr in request:" + httpGet.getURI().toString());

            // 执行请求
            CloseableHttpResponse response = httpclient.execute(httpGet);
            // 取响应的结果
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
    
    
                return;
            }
            HttpEntity entity = response.getEntity();

            Gson gson=new GsonBuilder().registerTypeAdapter(Map.class, new JsonDeserializer<Map>() {
    
    
                @Override
                public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                        throws JsonParseException{
    
    
                    Map<String,Object> resultMap=new HashMap<>(32);
                    JsonObject jsonObject = json.getAsJsonObject();
                    Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                    for (Map.Entry<String, JsonElement> entry : entrySet) {
    
    
                        resultMap.put(entry.getKey(),entry.getValue());
                    }
                    return resultMap;
                }
            }).create();
            
            Map<String, Object> parseObject  = gson.fromJson(EntityUtils.toString(entity), Map.class);
            //todo 对获取的数据进行操作
            Object result = parseObject.get("result");
            System.out.println("result=" + result);

            JsonArray arr = (JsonArray)result;
            //判断数据是否同步结束
            if(arr == null || arr.size() == 0) {
    
    
                //数据同步已完成
                break;
            }
            
            int size = arr.size();
            for (int i = 0; i < arr.size(); i++) {
    
    
                JsonObject obj = arr.get(i).getAsJsonObject();
                //obj中获取属性值,如userName
                String orgName = obj.get("userName").getAsString();
                System.out.println("userName=" + userName);
                if(i == size - 1) {
    
    
                    //获取本次拉取数据中最大的maxSyncSequence,作为下次的参数
                    syncSequence = Long.valueOf(obj.get("syncSequence").toString());
                }
            }
            System.out.println("maxSyncSequence=" + syncSequence);
        }
    }
}  

Сообщение использует запрос данных формы

import com.google.gson.Gson;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.net.URI;
import java.util.*;

/**
 * Post使用form-data请求
 **/
public class HttpClientUtils {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //接口地址
        String restSever = "http://127.0.0.1:8080/service/base/user/pwd/modify";
        // 应用标识
        String appKey = "xxxxxxxxxxxxxxxxxxx";
        // 系统签发给应用对接的密钥
        String pwd = "xxxxxxxxxxxxxxxxxxx";
        // 时间戳
        Long ts = Calendar.getInstance().getTime().getTime();
        // 随机数
        String once = RandomStringUtils.randomAlphanumeric(32);
        String signMethod = "SHA-256";

        // 创建HttpClient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String commonParamUrl = String.format("appKey=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, ts, once, signMethod);

        HttpPost httpPost = new HttpPost(restSever);
        // 签名数据
        String signData = TokenUtils.getSignature(pwd, restSever);
        // 添加header参数 appCode、timestamp、 signatureNonce、signature
        httpPost.addHeader("appKey", appKey);
        httpPost.addHeader("ts", ts.toString());
        httpPost.addHeader("once", once);
        httpPost.addHeader("once", once);
        httpPost.addHeader("signMethod", signMethod);
        System.out.println("once:" + once);
        httpPost.addHeader("signData", signData);
        httpPost.addHeader("tenantId", "1");
        System.out.println("headers:" + Arrays.toString(httpPost.getAllHeaders()));

        String urlStr = httpPost.getURI().toString();

        // 公共参数URL
        System.out.println("commonParamter:" + urlStr);

        if (StringUtils.endsWith(urlStr, "/")) {
    
    
            urlStr = StringUtils.removeEnd(urlStr, "/");
        }

        httpPost.setURI(new URI(urlStr));

        //httpClient 4.5版本的超时参数配置
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000).setSocketTimeout(5000).build();
        httpPost.setConfig(requestConfig);
        System.out.println("urlStr in request:" + httpPost.getURI().toString());

        //使用form-data格式往BODY里填充数据主体
        List<NameValuePair> parameters = new ArrayList<>();
        parameters.add(new BasicNameValuePair("newPwd", "123456"));
        parameters.add(new BasicNameValuePair("oldPwd", "123456"));
        parameters.add(new BasicNameValuePair("userId", "xxxxxxxxxxxxxxxxxxx"));
        HttpEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
        httpPost.setEntity(entity);

        // 执行请求
        CloseableHttpResponse response = httpclient.execute(httpPost);
        // 取响应的结果
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("statusCode:" + statusCode);
        HttpEntity responseEntity = response.getEntity();

        Gson gson = new Gson();
        Map<String, Object> parseObject  = gson.fromJson(EntityUtils.toString(responseEntity), Map.class);
        System.out.println("r:" + parseObject);
        //todo 对返回值进行处理
        String code = parseObject.get("code").toString();
        System.out.println("code:" + code);
        if(!"0".equals(code)) {
    
    
            System.out.println("error:" + parseObject.get("message").toString());
        }
        Object records = parseObject.get("result");

    }
}

Post использует запрос Json (унифицированный и часто используемый)

import com.google.gson.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.lang.reflect.Type;
import java.net.URI;
import java.util.*;

public class ResetPwd {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //接口地址
        String restSever = "http://xxxxx:8080/service/base/user/pwd/modify";

        // 应用标识
        String appKey = "xxxxxxxxxxxxxxxxxxx";
        // 系统签发给应用对接的密钥
        String pwd = "xxxxxxxxxxxxxxxxxxx";
        // 时间戳
        Long ts = Calendar.getInstance().getTime().getTime();
        // 随机数
        String once = RandomStringUtils.randomAlphanumeric(32);
        String signMethod = "SHA-256";

        JsonObject obj = new JsonObject();
        //请求参数
        obj.addProperty("userId", "xxxxxxxxxxxxxxxxx");
        obj.addProperty("oldPwd", "123456");
        obj.addProperty("newPwd", "180127");
        String bodyData = obj.toString();

        String commonParamUrl = String.format("appKey=%s" + "&" + "bodyData=%s" + "&" + "ts=%s" + "&" + "once=%s" + "&" + "signMethod=%s", appKey, bodyData, ts, once, signMethod);

        HttpPost httpPost = new HttpPost(restSever);
        System.out.println("请求参数:" + commonParamUrl);
        // 签名数据
        String signData = TokenUtils.getSignature(pwd, commonParamUrl);
        // 添加header参数 appCode、timestamp、 signatureNonce、signature
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
        httpPost.addHeader("appKey", appKey);
        httpPost.addHeader("ts", ts.toString());
        httpPost.addHeader("once", once);
        httpPost.addHeader("signMethod", signMethod);
        System.out.println("once:" + once);
        httpPost.addHeader("signData", signData);
        System.out.println("headers:" + Arrays.toString(httpPost.getAllHeaders()));

        httpPost.setEntity(new StringEntity(bodyData));
        String urlStr = httpPost.getURI().toString();

        // 公共参数URL
        System.out.println("commonParamter:" + urlStr);

        if (StringUtils.endsWith(urlStr, "/")) {
    
    
            urlStr = StringUtils.removeEnd(urlStr, "/");
        }

        httpPost.setURI(new URI(urlStr));
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000).setSocketTimeout(5000).build();
        httpPost.setConfig(requestConfig);
        System.out.println("urlStr in request:" + httpPost.getURI().toString());

        // 创建HttpClient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        // 执行请求
        CloseableHttpResponse response = httpclient.execute(httpPost);
        // 取响应的结果
        int statusCode = response.getStatusLine().getStatusCode();
        System.out.println("statusCode:" + statusCode);
        HttpEntity entity = response.getEntity();

        Gson gson = new Gson();
        Map<String, Object> parseObject  = gson.fromJson(EntityUtils.toString(entity), Map.class);
        System.out.println("r:" + parseObject);
        //todo 对返回值进行处理
        String code = parseObject.get("code").toString();
        System.out.println("code:" + code);
        if(!"0".equals(code)) {
    
    
            System.out.println("error:" + parseObject.get("message").toString());
        }
        Object records = parseObject.get("result");
        
    }
}

Класс метода обработки проверки подписи

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * 签名方法类
 */
public class TokenUtils {
    
    

    private static final Logger logger = LoggerFactory.getLogger(TokenUtils.class);

    private static String[] hexDigits = {
    
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e",
            "f"};

    public static String getSignature(String pwd, String paramUrl) {
    
    


        if (StringUtils.isNotBlank(paramUrl)) {
    
    
            try {
    
    
                paramUrl = URLDecoder.decode(paramUrl, "UTF-8");
            } catch (UnsupportedEncodingException e) {
    
    
                logger.error("生成signData失败:", e);
                throw new RuntimeException("生成signData失败:", e);
            }
        }

        String[] paraArray = new String[]{
    
    };
        if (StringUtils.isNotBlank(paramUrl)) {
    
    
            String[] queryArray = paramUrl.split("&");
            paraArray = (String[]) ArrayUtils.addAll(queryArray, paraArray);
        }

        Arrays.sort(paraArray);

        StringBuffer buffer = new StringBuffer();
        buffer.append(pwd);
        buffer.append(":");

        for (int i = 0; i < paraArray.length; i++) {
    
    
            buffer.append(paraArray[i]);
            buffer.append("&");
        }
        buffer.deleteCharAt(buffer.length() - 1);
        buffer.append(":");
        buffer.append(pwd);

        MessageDigest md = null;
        try {
    
    
            md = MessageDigest.getInstance("SHA-256");
            md.update(buffer.toString().getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
    
    
            logger.error("生成signData失败:", e);
            throw new RuntimeException("生成signData失败.", e);
        } catch (UnsupportedEncodingException e) {
    
    
            logger.error("生成signData失败:", e);
            throw new RuntimeException("生成signData失败.", e);
        }
        String encode = byteArrayToHexString(md.digest());
        return encode;
    }

    private static String byteArrayToHexString(byte[] byteArray) {
    
    
        StringBuffer sb = new StringBuffer();
        for (byte byt : byteArray) {
    
    
            sb.append(byteToHexString(byt));
        }
        return sb.toString();
    }

    private static String byteToHexString(byte byt) {
    
    
        int n = byt;
        if (n < 0)
            n = 256 + n;
        return hexDigits[n / 16] + hexDigits[n % 16];
    }
}

Guess you like

Origin blog.csdn.net/weixin_42306823/article/details/122857790