第三方应用使用SDK调系统接口的签名加密解密实现方案

发布时间 2023-08-04 17:29:05作者: 夏威夷8080

具体逻辑参考《java/springboot服务第三方接口安全签名(Signature)实现方案》,这边只是做了更细化的代码实现,另外也没有完全贴出所有代码。

封装SDK的pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>xiaweiyi-sample-parent</artifactId>
        <groupId>com.xxx</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
<groupId>com.xxx</groupId>
    <artifactId>xiaweiyi-xxxx-sdk</artifactId>
    <version>1.0.0</version>
    <name>xiaweiyi-xxxx-sdk</name>

    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <fastjson.version>1.2.74</fastjson.version>
        <httpcomponents.version>4.5.14</httpcomponents.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpcomponents.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpmime</artifactId>
            <version>${httpcomponents.version}</version>
        </dependency>

        <!--常用工具类 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!--io常用工具类 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <!-- 工具类 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 

 封装的接口调用类

 

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;

public class MyHttpUtil {
    private static final String SUCC_PRE = "2";
    private static final String REDIRECT_PRE = "3";

    public MyHttpUtil() {
    }

    public static String doGetMy(MyConfig myConfig, Map<String, String> path, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.GET, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            Response response = Client.execute(request);
            return response.getBody();
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doGetMy(MyConfig myConfig, Map<String, String> path, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            Request request = new Request(Method.GET, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            Response response = Client.execute(request);
            return response.getBody();
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static HttpResponse doGetResponse(MyConfig myConfig, Map<String, String> path, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            HttpResponse httpResponse = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.GET_RESPONSE, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            Response response = Client.execute(request);
            return response.getResponse();
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostFormMy(MyConfig myConfig, Map<String, String> path, Map<String, String> paramMap, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.POST_FORM, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBodys(paramMap);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostFormMy(MyConfig myConfig, Map<String, String> path, Map<String, Object> paramMap, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            }

            Request request = new Request(Method.POST_FORM, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBodys(paramMap);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static HttpResponse doPostFormImgMy(MyConfig myConfig, Map<String, String> path, Map<String, String> paramMap, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            HttpResponse response = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.POST_FORM_RESPONSE, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBodys(paramMap);
            Response response1 = Client.execute(request);
            return response1.getResponse();
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostStringMy(MyConfig myConfig, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.POST_STRING, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setStringBody(body);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostStringMy(MyConfig myConfig, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            Request request = new Request(Method.POST_STRING, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setStringBody(body);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static HttpResponse doPostStringImgMy(MyConfig myConfig, Map<String, String> path, String body, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            HttpResponse responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.POST_STRING_RESPONSE, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setStringBody(body);
            Response response = Client.execute(request);
            return response.getResponse();
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostBytesMy(MyConfig myConfig, Map<String, String> path, byte[] bytesBody, Map<String, String> querys, String accept, String contentType, Map<String, String> header) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (bytesBody != null) {
                headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            if (header != null) {
                headers.putAll(header);
            }

            Request request = new Request(Method.POST_BYTES, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBytesBody(bytesBody);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostBytesMy(MyConfig myConfig, Map<String, String> path, byte[] bytesBody, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (bytesBody != null) {
                headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            Request request = new Request(Method.POST_BYTES, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBytesBody(bytesBody);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPostFileFormMy(MyConfig myConfig, Map<String, String> path, Map<String, Object> paramMap, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "multipart/form-data;charset=UTF-8");
            }

            Request request = new Request(Method.POST_FILE, httpSchema + myConfig.getHost(), (String)path.get(httpSchema), myConfig.getAppKey(), myConfig.getAppSecret(), Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            request.setBodys(paramMap);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPutStringMy(MyConfig myConfig, Map<String, String> path, String body, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(body)) {
                headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(body));
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            Request request = new Request(Method.PUT_STRING, httpSchema + myConfig.host, (String)path.get(httpSchema), myConfig.appKey, myConfig.appSecret, Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setStringBody(body);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doPutBytesMy(MyConfig myConfig, Map<String, String> path, byte[] bytesBody, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (bytesBody != null) {
                headers.put("Content-MD5", MessageDigestUtil.base64AndMD5(bytesBody));
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            } else {
                headers.put("Content-Type", "application/text;charset=UTF-8");
            }

            Request request = new Request(Method.PUT_BYTES, httpSchema + myConfig.host, (String)path.get(httpSchema), myConfig.appKey, myConfig.appSecret, Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setBytesBody(bytesBody);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    public static String doDeleteMy(MyConfig myConfig, Map<String, String> path, Map<String, String> querys, String accept, String contentType) throws Exception {
        String httpSchema = (String)path.keySet().toArray()[0];
        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
            String responseStr = null;
            Map<String, String> headers = new HashMap();
            if (StringUtils.isNotBlank(accept)) {
                headers.put("Accept", accept);
            } else {
                headers.put("Accept", "*/*");
            }

            if (StringUtils.isNotBlank(contentType)) {
                headers.put("Content-Type", contentType);
            }

            Request request = new Request(Method.DELETE, httpSchema + myConfig.host, (String)path.get(httpSchema), myConfig.appKey, myConfig.appSecret, Constants.DEFAULT_TIMEOUT);
            request.setHeaders(headers);
            request.setQuerys(querys);
            Response response = Client.execute(request);
            return getResponseResult(response);
        } else {
            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
        }
    }

    private static String getResponseResult(Response response) {
        String responseStr = null;
        int statusCode = response.getStatusCode();
        if (!String.valueOf(statusCode).startsWith("2") && !String.valueOf(statusCode).startsWith("3")) {
            String msg = response.getErrorMessage();
            responseStr = response.getBody();
        } else {
            responseStr = response.getBody();
        }

        return responseStr;
    }
}

 



数据加密类

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SignUtil {
    private static final Logger Logger = LoggerFactory.getLogger(StringUtils.class);

    public SignUtil() {
    }

    public static String sign(String secret, String method, String path, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys, List<String> signHeaderPrefixList) {
        try {
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            byte[] keyBytes = secret.getBytes("UTF-8");
            hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
            String stringToSign = buildStringToSign(method, path, headers, querys, bodys, signHeaderPrefixList);
            if (Logger.isDebugEnabled()) {
                Logger.debug("StringToSign:\n{}", stringToSign);
            }

            return new String(Base64.encodeBase64(hmacSha256.doFinal(stringToSign.getBytes("UTF-8"))), "UTF-8");
        } catch (Exception var10) {
            throw new RuntimeException(var10);
        }
    }

    private static String buildStringToSign(String method, String path, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys, List<String> signHeaderPrefixList) {
        StringBuilder sb = new StringBuilder();
        sb.append(method.toUpperCase()).append("\n");
        if (null != headers) {
            if (null != headers.get("Accept")) {
                sb.append((String)headers.get("Accept"));
                sb.append("\n");
            }

            if (null != headers.get("Content-MD5")) {
                sb.append((String)headers.get("Content-MD5"));
                sb.append("\n");
            }

            if (null != headers.get("Content-Type")) {
                String contentType = (String)headers.get("Content-Type");
                if (contentType.contains("boundary")) {
                    String[] strings = contentType.split(";");
                    String[] var9 = strings;
                    int var10 = strings.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        String string = var9[var11];
                        if (!string.contains("boundary")) {
                            sb.append(string);
                            sb.append(";");
                        }
                    }

                    sb.deleteCharAt(sb.toString().length() - 1);
                } else {
                    sb.append(contentType);
                }

                sb.append("\n");
            }

            if (null != headers.get("Date")) {
                sb.append((String)headers.get("Date"));
                sb.append("\n");
            }
        }

        sb.append(buildHeaders(headers, signHeaderPrefixList));
        sb.append(buildResource(path, querys, bodys));
        return sb.toString();
    }

    private static String buildResource(String path, Map<String, String> querys, Map<String, String> bodys) {
        StringBuilder sb = new StringBuilder();
        if (!StringUtils.isBlank(path)) {
            sb.append(path);
        }

        Map<String, String> sortMap = new TreeMap();
        Iterator var5;
        Entry body;
        if (null != querys) {
            var5 = querys.entrySet().iterator();

            while(var5.hasNext()) {
                body = (Entry)var5.next();
                if (!StringUtils.isBlank((CharSequence)body.getKey())) {
                    sortMap.put(String.valueOf(body.getKey()), String.valueOf(body.getValue()));
                }
            }
        }

        if (null != bodys) {
            var5 = bodys.entrySet().iterator();

            while(var5.hasNext()) {
                body = (Entry)var5.next();
                if (!StringUtils.isBlank((CharSequence)body.getKey())) {
                    sortMap.put(String.valueOf(body.getKey()), String.valueOf(body.getValue()));
                }
            }
        }

        StringBuilder sbParam = new StringBuilder();
        Iterator var9 = sortMap.entrySet().iterator();

        while(var9.hasNext()) {
            Entry<String, String> item = (Entry)var9.next();
            if (!StringUtils.isBlank((CharSequence)item.getKey())) {
                if (0 < sbParam.length()) {
                    sbParam.append("&");
                }

                sbParam.append((String)item.getKey());
                if (!StringUtils.isBlank((CharSequence)item.getValue())) {
                    sbParam.append("=").append((String)item.getValue());
                }
            }
        }

        if (0 < sbParam.length()) {
            sb.append("?");
            sb.append(sbParam);
        }

        return sb.toString();
    }

    private static String buildHeaders(Map<String, String> headers, List<String> signHeaderPrefixList) {
        StringBuilder sb = new StringBuilder();
        if (null != signHeaderPrefixList) {
            signHeaderPrefixList.remove("x-xwy-signature");
            signHeaderPrefixList.remove("Accept");
            signHeaderPrefixList.remove("Content-MD5");
            signHeaderPrefixList.remove("Content-Type");
            signHeaderPrefixList.remove("Date");
            Collections.sort(signHeaderPrefixList);
        }

        if (null != headers) {
            Map<String, String> sortMap = new TreeMap();
            sortMap.putAll(headers);
            StringBuilder signHeadersStringBuilder = new StringBuilder();
            Iterator var5 = sortMap.entrySet().iterator();

            while(var5.hasNext()) {
                Entry<String, String> header = (Entry)var5.next();
                if (isHeaderToSign((String)header.getKey(), signHeaderPrefixList)) {
                    sb.append((String)header.getKey());
                    sb.append(":");
                    if (!StringUtils.isBlank((CharSequence)header.getValue())) {
                        sb.append((String)header.getValue());
                    }

                    sb.append("\n");
                    if (0 < signHeadersStringBuilder.length()) {
                        signHeadersStringBuilder.append(",");
                    }

                    signHeadersStringBuilder.append((String)header.getKey());
                }
            }

            headers.put("x-xwy-signature-headers", signHeadersStringBuilder.toString());
        }

        return sb.toString();
    }

    private static boolean isHeaderToSign(String headerName, List<String> signHeaderPrefixList) {
        if (StringUtils.isBlank(headerName)) {
            return false;
        } else if (headerName.startsWith("x-xwy-")) {
            return true;
        } else {
            if (null != signHeaderPrefixList) {
                Iterator var2 = signHeaderPrefixList.iterator();

                while(var2.hasNext()) {
                    String signHeaderPrefix = (String)var2.next();
                    if (headerName.equalsIgnoreCase(signHeaderPrefix)) {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}

 


Server端的拦截器

import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 拦截给第三方应用提供的接口,校验数据安全性、身份合法性等
 */
@Slf4j
public class ThirdApplicationInterceptor extends HandlerInterceptorAdapter {

    Cache<String, String> cache = CacheBuilder.newBuilder()
            .maximumSize(100)
            .expireAfterWrite(1, TimeUnit.MINUTES)
            .build();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("-------->进入ThirdApplicationInterceptor拦截器");
        String method = request.getMethod();

        String path = request.getServletPath();// /test/sync
        String platId = request.getParameter("platId");
        Map<String, String> querys = new HashMap<>();
        querys.put("platId", platId);
        String reqUrl = request.getRequestURL().toString(); // http://localhost:8000/xiaweiyi/test/sync
        String requestURI = request.getRequestURI(); // /xiaweiyi/test/sync
        String contextPath = request.getContextPath(); // /xiaweiyi
        log.info("-------->获取到method:{},path:{},platId:{},pathInfo:{},queryString:{},reqUrl:{},requestURI:{},contextPath:{}",
                method, path, platId, 1, 1, reqUrl, requestURI, contextPath);

        String signature = request.getHeader("x-xwy-signature");
        String timestamp = request.getHeader("x-xwy-timestamp");
        String key = request.getHeader("x-xwy-key");
        String nonce = request.getHeader("x-xwy-nonce");

        String accept = request.getHeader("Accept");
        String cm5 = request.getHeader("Content-MD5");
        String contentType = request.getHeader("Content-Type");

        // 根据appkey校验应用,查询appSec
        // 根据timestamp校验超时
        // 根据signature验签,防数据篡改
        // 根据nonce,防重放和日志查询

        ApplicationInfoMapper applicationInfoMapper = SpringUtils.getBean(ApplicationInfoMapper.class);
        String appKey = key;
        ApplicationInfo applicationInfo = applicationInfoMapper.selectOne(new QueryWrapper<ApplicationInfo>().lambda().eq(ApplicationInfo::getAppKey, appKey));
        if (applicationInfo == null) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            WebUtils.renderJson(response, R.builder().code(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getCode()).msg(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getDesc()).build());
            log.info("-------->appKey的应用不存在-------");
        }

        String appSecret = applicationInfo.getAppSecret();

        Map headers = new HashMap();
        headers.put("x-xwy-timestamp", timestamp);
        headers.put("x-xwy-nonce", nonce);
        headers.put("x-xwy-key", appKey);
        headers.put("Accept", accept);
        headers.put("Content-MD5", cm5);
        headers.put("Content-Type", contentType);
        String sign = SignUtil.sign(appSecret, method, requestURI, headers, querys, querys, null);
        if (!sign.equals(signature)) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            WebUtils.renderJson(response, R.builder().code(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getCode()).msg(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getDesc()).build());
            log.info("-------->验签不通过-------");
        }

        long t = System.currentTimeMillis() - Long.valueOf(timestamp);
        boolean b = TimeUnit.MILLISECONDS.toMinutes(t) > 1;
        if (b) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            WebUtils.renderJson(response, R.builder().code(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getCode()).msg(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getDesc()).build());
            log.info("-------->请求超时-------");
        }

        String c = cache.getIfPresent(nonce);
        if (StringUtils.isNotBlank(c)) {
            response.setStatus(HttpStatus.HTTP_UNAUTHORIZED);
            WebUtils.renderJson(response, R.builder().code(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getCode()).msg(com.xxx.test.sample.comn.exception.ResultCode.IN_VALID_REQUEST.getDesc()).build());
            log.info("-------->请勿重复请求-------");
        }

        cache.put(nonce, "1");
        return Boolean.TRUE;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}

 

 

Server端提供的接口

@RestController
@RequestMapping("/test")
@Api(value = "第三方调用的接口", tags = "第三方调用的接口")
@Slf4j
public class ThirdPartController {


    @PostMapping("/sync")
    @ApiOperation(value = "同步信息")
    public ResponseResult sync(@ApiParam("应用id") @RequestParam String platId) throws Exception{
        
        List<TreeDTO> dtos = service.sync(platId);
        return ResponseResult.success(dtos);
    }

}

 

 

调用SDK接口测试

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 夏威夷8080
 * @Date: 2023/8/3 10:00
 */
@Slf4j
public class ThirdMock {

    XwyTieasyProperties vcpVideoProperties = new XwyTieasyProperties();


    public static void main(String[] args) {
        ThirdMock thirdMock = new ThirdMock();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("url", "/test/sync");
        JSONObject result = thirdMock.mockSync(jsonObject);
        log.info("result:{}", result.toString());
    }

    public JSONObject mockSync(JSONObject jsonObject) {

        MyConfig myConfig = new MyConfig();
        myConfig.setHost(vcpVideoProperties.getUrl()); //平台(nginx)IP 和端口
        myConfig.setAppKey(vcpVideoProperties.getAppkey()); //合作方 key
        myConfig.setAppSecret(vcpVideoProperties.getAppSecret());//合作方 Secret

        Map<String, String> querys = new HashMap<>();
        querys.put("platId", "11111111111111");
//        querys.put("type", "2");

        JSONObject result = null;
        try {
            String body = jsonObject.toString();
            log.info("请求的body:{}",body);
            String apiPath = (String) jsonObject.get("url");
            log.info("请求的apiPath:{}",apiPath);
            String resultStr = MyHttpUtil.doPostStringMy(myConfig, buildXwyTieasyPara(apiPath), body, querys,
                    "*/*","application/json");
            log.info("获取原始返回报文---"+resultStr);
            log.info("报文格式后的数据"+ JSONUtil.parse(resultStr).toStringPretty());
            result = JSONObject.parseObject(resultStr);
            //R result = JSONUtil.toBean(resultStr,new TypeReference<R>(){},true);
            return result;
        }catch (Exception e){
            log.error("请求平台报错,错误信息:{}", Throwables.getStackTraceAsString(e));

        }

        R<String> r = new R<>("200","访问异常!");
        result = (JSONObject)JSONObject.toJSON(r);
        return result;
    }

    public Map<String, String> buildXwyTieasyPara(String apiPath){
        final String getSecurityApi = vcpVideoProperties.getMyPath() + apiPath; // 接口路径
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("http://", getSecurityApi); // 要是https就换成https
            }
        };
        return path;
    }
}