|
|
|
|
@ -111,6 +111,7 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@VisibleForTesting
|
|
|
|
|
@SuppressWarnings("EnhancedSwitchMigration")
|
|
|
|
|
Integer convertSmsTemplateAuditStatus(Integer templateStatus) {
|
|
|
|
|
switch (templateStatus) {
|
|
|
|
|
case 0: return SmsTemplateAuditStatusEnum.CHECKING.getStatus();
|
|
|
|
|
@ -134,20 +135,25 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
|
|
|
|
.map(entry -> percentCode(entry.getKey()) + "=" + percentCode(String.valueOf(entry.getValue())))
|
|
|
|
|
.collect(Collectors.joining("&"));
|
|
|
|
|
|
|
|
|
|
// 2.1 请求 Header
|
|
|
|
|
// 2. 请求 Body
|
|
|
|
|
String requestBody = ""; // 短信 API 为 RPC 接口,query parameters 在 uri 中拼接,因此 request body 如果没有特殊要求,设置为空
|
|
|
|
|
String hashedRequestPayload = DigestUtil.sha256Hex(requestBody);
|
|
|
|
|
|
|
|
|
|
// 3.1 请求 Header
|
|
|
|
|
TreeMap<String, String> headers = new TreeMap<>();
|
|
|
|
|
headers.put("host", HOST);
|
|
|
|
|
headers.put("x-acs-version", VERSION);
|
|
|
|
|
headers.put("x-acs-action", apiName);
|
|
|
|
|
headers.put("x-acs-date", FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("GMT")).format(new Date()));
|
|
|
|
|
headers.put("x-acs-signature-nonce", IdUtil.randomUUID());
|
|
|
|
|
headers.put("x-acs-content-sha256", hashedRequestPayload);
|
|
|
|
|
|
|
|
|
|
// 2.2 构建签名 Header
|
|
|
|
|
// 3.2 构建签名 Header
|
|
|
|
|
StringBuilder canonicalHeaders = new StringBuilder(); // 构造请求头,多个规范化消息头,按照消息头名称(小写)的字符代码顺序以升序排列后拼接在一起
|
|
|
|
|
StringBuilder signedHeadersBuilder = new StringBuilder(); // 已签名消息头列表,多个请求头名称(小写)按首字母升序排列并以英文分号(;)分隔
|
|
|
|
|
headers.entrySet().stream().filter(entry -> entry.getKey().toLowerCase().startsWith("x-acs-")
|
|
|
|
|
|| entry.getKey().equalsIgnoreCase("host")
|
|
|
|
|
|| entry.getKey().equalsIgnoreCase("content-type"))
|
|
|
|
|
|| "host".equalsIgnoreCase(entry.getKey())
|
|
|
|
|
|| "content-type".equalsIgnoreCase(entry.getKey()))
|
|
|
|
|
.sorted(Map.Entry.comparingByKey()).forEach(entry -> {
|
|
|
|
|
String lowerKey = entry.getKey().toLowerCase();
|
|
|
|
|
canonicalHeaders.append(lowerKey).append(":").append(String.valueOf(entry.getValue()).trim()).append("\n");
|
|
|
|
|
@ -155,13 +161,13 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
|
|
|
|
});
|
|
|
|
|
String signedHeaders = signedHeadersBuilder.substring(0, signedHeadersBuilder.length() - 1);
|
|
|
|
|
|
|
|
|
|
// 3. 请求 Body
|
|
|
|
|
String requestBody = ""; // 短信 API 为 RPC 接口,query parameters 在 uri 中拼接,因此 request body 如果没有特殊要求,设置为空。
|
|
|
|
|
String hashedRequestBody = DigestUtil.sha256Hex(requestBody);
|
|
|
|
|
|
|
|
|
|
// 4. 构建 Authorization 签名
|
|
|
|
|
String canonicalRequest = "POST" + "\n" + "/" + "\n" + queryString + "\n"
|
|
|
|
|
+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestBody;
|
|
|
|
|
String canonicalRequest = "POST" + "\n" +
|
|
|
|
|
"/" + "\n" +
|
|
|
|
|
queryString + "\n" +
|
|
|
|
|
canonicalHeaders + "\n" +
|
|
|
|
|
signedHeaders + "\n" +
|
|
|
|
|
hashedRequestPayload;
|
|
|
|
|
String hashedCanonicalRequest = DigestUtil.sha256Hex(canonicalRequest);
|
|
|
|
|
String stringToSign = "ACS3-HMAC-SHA256" + "\n" + hashedCanonicalRequest;
|
|
|
|
|
String signature = SecureUtil.hmacSha256(properties.getApiSecret()).digestHex(stringToSign); // 计算签名
|
|
|
|
|
@ -188,4 +194,4 @@ public class AliyunSmsClient extends AbstractSmsClient {
|
|
|
|
|
.replace("%7E", "~"); // 波浪号 "%7E" 被替换为 "~"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|