AKSK安全认证 Posted on 2021-07-29 | Edited on 2023-05-09 | In javaWeb | Views: 蓝卓开发者社区 APP集成 ∣ 深度集成方案 supOS SDK for Java 开发指南 123456789101112131415161718String apibaseURL = System.getenv("SUPOS_SUPOS_ADDRESS");//封装消息体String body = "{\n" + "\t\"sender\": \"admin\",\n" + "\t\"source\": \"system\",\n" + "\t\"type\":\"stationLetter\",\n" + "\t\"receivers\": [\"xwj\"],\n" + "\t\"content\":{\n" + "\t\t\"title\":\"aaaaa\",\n" + "\t\t\"text\":\"aaa\"\n" + "\t}\n" + "}";//调用openapi签名工具类发送请求Map<String, String> headMap = new HashMap<String, String>(){{ put("X-MC-Date","..."); put("X-MC-Type","...");}};String response = SignUtil.doHttpMethod(apiBaseURL,"/api/openapi/notification/v1/message", HttpMethod.POST, JSON.parseObject(body), headMap); SignUtil 签名的工具类 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153import cn.hutool.json.JSONObject;import com.bluetron.eco.sdk.dto.common.SuposConfig;import org.springframework.http.HttpMethod;import com.google.common.net.HttpHeaders;import lombok.extern.slf4j.Slf4j;import org.apache.commons.codec.digest.HmacAlgorithms;import org.apache.commons.codec.digest.HmacUtils;import org.apache.commons.collections4.MapUtils;import org.apache.commons.lang3.StringUtils;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.methods.*;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.util.EntityUtils;import java.nio.charset.StandardCharsets;import java.util.*;@Slf4jpublic class SignUtil { /** * 通过AK/SK签名 发送HTTP请求调用open api接口 * @param apiPath api的请求路径 如:/openapi/users/v1?page=1&per_page=2 * @param method HttpMethod * @param jsonBody 当method是post put等请求时,所携带的body * @param headMap 签名需要用到的头 * @return * @throws Exception */ public static String doHttpMethod(String apiPath, HttpMethod method, JSONObject jsonBody, Map<String, String> headMap) throws Exception { log.info(">>>>>>>>>>>>> AK/SK 请求, apiPath: {} , method: {} ,jsonBody: {}, headMap: {}<<<<<<<<<<<<<<<<", apiPath, method, jsonBody, headMap); SignRequest request = new SignRequest(); request.setSignUrl(SuposConfig.getSuposApiAddress(), apiPath); request.setAppId(SuposConfig.getAppId()); request.setAppSecret(SuposConfig.getSecretKey()); request.setHttpMethod(method); request.addHeader(HttpHeaders.CONTENT_TYPE, "application/json"); if (null != jsonBody) { request.setBody(jsonBody.toString()); } HttpRequestBase requestBase = createSignatureRequest(request, headMap); CloseableHttpClient client = HttpClients.custom().build(); HttpResponse response = client.execute(requestBase); int statusCode = response.getStatusLine().getStatusCode(); HttpEntity resEntity = response.getEntity(); String result = null; if (resEntity != null) { result = EntityUtils.toString(resEntity, "UTF-8"); } log.info(">>>>>>>>>>>>> AK/SK 响应状态码: {} , 响应内容: {} <<<<<<<<<<<<<<<<", statusCode, result); return result; } /** * 创建一个具有AKSK签名的HTTP CLIENT请求 * request 加签参数 */ private static HttpRequestBase createSignatureRequest(SignRequest request, Map<String, String> headMap) { HttpRequestBase httpRequest; StringEntity entity; HttpMethod httpMethod = request.getHttpMethod(); String content = request.getBody(); String url = request.getSignUrl(); switch (httpMethod) { case POST: HttpPost postMethod = new HttpPost(url); if (StringUtils.isNotEmpty(content)) { entity = new StringEntity(content, StandardCharsets.UTF_8); postMethod.setEntity(entity); } httpRequest = postMethod; break; case PUT: HttpPut putMethod = new HttpPut(url); if (StringUtils.isNotEmpty(content)) { entity = new StringEntity(content, StandardCharsets.UTF_8); putMethod.setEntity(entity); } httpRequest = putMethod; break; case PATCH: HttpPatch patchMethod = new HttpPatch(url); if (StringUtils.isNotEmpty(content)) { entity = new StringEntity(content, StandardCharsets.UTF_8); patchMethod.setEntity(entity); } httpRequest = patchMethod; break; case GET: httpRequest = new HttpGet(url); break; case DELETE: httpRequest = new HttpDelete(url); break; case OPTIONS: httpRequest = new HttpOptions(url); break; default: if (httpMethod != HttpMethod.HEAD) { throw new RuntimeException("Unknown HTTP method name: " + httpMethod); } httpRequest = new HttpHead(url); break; } //获取签名头 Map<String, String> headers = getSignatureHeader(request, headMap); if (MapUtils.isNotEmpty(headMap)) { headers.putAll(headMap); } Iterator<String> iterator = headers.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); httpRequest.addHeader(key, headers.get(key)); } return httpRequest; } //获取AK/SK加签后的签名头 //request 加签参数 public static Map<String, String> getSignatureHeader(SignRequest request, Map<String, String> headMap) { Map<String, String> headers = request.getHeaders(); StringBuffer sb = new StringBuffer(); sb.append(request.getHttpMethod().toString()).append("\n") .append(request.getSignUrl()).append("\n") .append(headers.get(HttpHeaders.CONTENT_TYPE)).append("\n"); //CanonicalQueryString if (StringUtils.isNotEmpty(request.getQueryString())) { sb.append(request.getQueryString().trim()); } sb.append("\n").append(getCanonicalCustomHeaders(headMap).toString().trim()); log.info(">>>>>>>>>>>>> AK/SK 签名源内容:\n{} \n<<<<<<<<<<<<<<<<", sb); log.info("appSecret: {}", request.getAppSecret()); HmacUtils hmacSha256 = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, request.getAppSecret()); String signature = hmacSha256.hmacHex(sb.toString()); String finalSignature = "Sign " + request.getAppId() + "-" + signature; headers.put("Authorization", finalSignature); log.info(">>>>>>>>>>>>> AK/SK 签名结果:Authorization : {} <<<<<<<<<<<<<<<<", finalSignature); return headers; } //自定义的请求头 private static String getCanonicalCustomHeaders(Map<String, String> headMap) { return "x-mc-date:" + headMap.get("X-MC-Date") + ";x-mc-type:" + headMap.get("X-MC-Type"); }} -------------The End-------------