数据服务api加密方式
md5 + 签名认证
复制代码java
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
package com.alibaba.dt.dataphin;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.SSLContext;
import java.io.Closeable;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* postman方式调用API示例
* @author: 夜雨
* @date: 2020/12/15
* @version: V1.0.0
*/
public class PostManDemo {
/**
* 访问域名或ip
*/
private static final String HOST = "127.0.0.1:8080";
/**
* 应用appKey
*/
private static final String APP_KEY = "103787611";
/**
* 应用appSecret
*/
private static final String APP_SECRET = "1234hupacoc07ll7if586g72dvyr8v3o";
/**
* apiId
*/
private static final String API_ID = "1254131194177711110";
/**
* content-md5
* 请求body MD5,body可以参考SDK中请求参数封装类QueryParamRequest,转成json字符串
* String jsonStr = JSONObject.toJSONString(queryParamRequest);
* 也可直接按以下字符串格式自行封装
* conditions为请求参数(查询条件),returnFields为返回参数
*/
private final static String bodyJsonStr = "{\"conditions\":{\"name\":\"应用名称1\"},\"returnFields\":[\"id\",\"name\"],\"useModelCache\":false,\"useResultCache\":false}";
private static final Map<String, String> headers = new HashMap<String, String>();
/**
* //TODO 执行此方法之前,请按照实际情况(可以从oneservice中拿到相关参数值)替换以下参数值
* @see com.alibaba.dt.dataphin.PostManDemo#HOST
* @see com.alibaba.dt.dataphin.PostManDemo#APP_KEY
* @see com.alibaba.dt.dataphin.PostManDemo#APP_SECRET
* @see com.alibaba.dt.dataphin.PostManDemo#API_ID
*
*/
public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
//生成headers
createHears();
//body
System.out.println("请求body:"+bodyJsonStr);
//初始化httpclient
init();
//获取返回结果
String result = sendSyncRequest(headers, bodyJsonStr.getBytes("UTF-8"));
System.out.println("返回结果:");
System.out.println(result);
}
private static void createHears() throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
//date,设置请求头中的时间戳
Date current = new Date();
headers.put("date", getHttpDateHeaderValue(current));
System.out.println("生成header[date]:"+getHttpDateHeaderValue(current));
//x-ca-timestamp,设置请求头中的时间戳,以timeIntervalSince1970的形式
headers.put("x-ca-timestamp", String.valueOf(current.getTime()));
System.out.println("生成header[x-ca-timestamp]:"+String.valueOf(current.getTime()));
//x-ca-nonce,请求放重放Nonce,15分钟内保持唯一,建议使用UUID
// String uuid = UUID.randomUUID().toString();
// headers.put("x-ca-nonce", uuid);
// System.out.println("生成header[x-ca-nonce]:"+ uuid);
// //user-agent,设置请求头中的UserAgent
// System.out.println("生成header[user-agent]:ALIYUN-ANDROID-DEMO");
//host,设置请求头中的主机地址
headers.put("host", HOST);
System.out.println("生成header[host]:"+ HOST);
//x-ca-key,设置请求头中的Api绑定的的AppKey
headers.put("x-ca-key", APP_KEY);
System.out.println("生成header[x-ca-key]:"+ APP_KEY);
// //ca_version,设置签名版本号
// System.out.println("生成header[ca_version]:"+ 1);
//content-type,设置请求数据类型
headers.put("content-type", "application/json; charset=utf-8");
System.out.println("生成header[content-type]:application/json; charset=utf-8");
//accept,设置应答数据类型
headers.put("accept", "application/json; charset=utf-8");
System.out.println("生成header[accept]:application/json; charset=utf-8");
//x-ca-signature-method,签名加密方式
headers.put("x-ca-signature-method", "HmacSHA256");
System.out.println("生成header[x-ca-signature-method]:HmacSHA256");
String md5 = base64AndMD5(bodyJsonStr.getBytes("UTF-8"));
headers.put("content-md5", md5);
System.out.println("生成header[content-md5]:"+md5);
//x-ca-signature,签名用作服务器校验
String stringToSign = buildStringToSign(headers);
String signature = sign(stringToSign);
headers.put("x-ca-signature",signature);
System.out.println("生成header[x-ca-signature]:"+signature);
//x-ca-stage,生产环境标识
headers.put("x-ca-stage","RELEASE");
System.out.println("生成header[x-ca-stage]:RELEASE");
//x-ca-signature-headers,同时所有加入签名的头的列表,需要用逗号分隔形成一个字符串,加入一个新HTTP头@"X-Ca-Signature-Headers"
System.out.println("生成header[x-ca-signature-headers]:"+headers.get("x-ca-signature-headers"));
}
private static String getHttpDateHeaderValue(Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
return dateFormat.format(date);
}
public static String base64AndMD5(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("bytes can not be null");
}
try {
final MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
md.update(bytes);
byte[] md5Result = md.digest();
String base64Result = Base64.encodeBase64String(md5Result);
/*
* 正常情况下,base64的结果为24位,因与服务器有约定,在超过24位的情况下,截取前24位
*/
return base64Result.length() > 24 ? base64Result.substring(0, 23) : base64Result;
} catch (final NoSuchAlgorithmException e) {
throw new IllegalArgumentException("unknown algorithm MD5");
}
}
//换行符
private static final String CLOUDAPI_LF = "\n";
private static final String HTTP_METHOD = "POST";
/**
* path为oneservice创建的API指定的请求方式(get或者list)+API_ID生成
*/
private static final String PATH = "/get/"+API_ID;
private static final String ENV = "PROD";
private static final String URL = PATH+"?appKey="+APP_KEY+"&env="+ENV;
/**
* 构建需要参与签名的字符串
*/
public static String buildStringToSign(Map<String, String> headers) {
StringBuilder sb = new StringBuilder();
sb.append(HTTP_METHOD).append(CLOUDAPI_LF);
//如果有@"Accept"头,这个头需要参与签名
if (headers.get("accept") != null) {
sb.append(headers.get("accept"));
}
sb.append(CLOUDAPI_LF);
//如果有@"Content-MD5"头,这个头需要参与签名
if (headers.get("content-md5") != null) {
sb.append(headers.get("content-md5"));
}
sb.append(CLOUDAPI_LF);
//如果有@"Content-Type"头,这个头需要参与签名
if (headers.get("content-type") != null) {
sb.append(headers.get("content-type"));
}
sb.append(CLOUDAPI_LF);
//签名优先读取HTTP_CA_HEADER_DATE,因为通过浏览器过来的请求不允许自定义Date(会被浏览器认为是篡改攻击)
if (headers.get("date") != null) {
sb.append(headers.get("date"));
}
sb.append(CLOUDAPI_LF);
//将headers合成一个字符串
sb.append(buildHeaders(headers));
//url
sb.append(URL);
return sb.toString();
}
/**
* 将headers合成一个字符串
* 需要注意的是,HTTP头需要按照字母排序加入签名字符串
* 同时所有加入签名的头的列表,需要用逗号分隔形成一个字符串,加入一个新HTTP头@"X-Ca-Signature-Headers"
*/
private static String buildHeaders(Map<String, String> headers) {
//使用TreeMap,默认按照字母排序
Map<String, String> headersToSign = new TreeMap<String, String>();
StringBuilder signHeadersStringBuilder = new StringBuilder();
int flag = 0;
for (Map.Entry<String, String> header : headers.entrySet()) {
if (header.getKey().startsWith("x-ca-")) {
if (flag != 0) {
signHeadersStringBuilder.append(",");
}
flag++;
signHeadersStringBuilder.append(header.getKey());
headersToSign.put(header.getKey(), header.getValue());
}
}
//同时所有加入签名的头的列表,需要用逗号分隔形成一个字符串,加入一个新HTTP头@"X-Ca-Signature-Headers"
headers.put("x-ca-signature-headers",signHeadersStringBuilder.toString());
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> e : headersToSign.entrySet()) {
sb.append(e.getKey()).append(':').append(e.getValue()).append(CLOUDAPI_LF);
}
return sb.toString();
}
/**
* 生成签名串
* @param stringToSign
* @return
*/
public static String sign(String stringToSign) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] keyBytes = APP_SECRET.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacSHA256"));
String signature = new String(Base64.encodeBase64(hmacSha256.doFinal(stringToSign.getBytes("UTF-8"))));
return signature;
}
public static String sendSyncRequest(Map<String, String> headers,byte[] body) {
HttpUriRequest httpRequest = buildRequest(headers,body);
CloseableHttpResponse httpResponse = null;
try {
httpResponse = httpClient.execute(httpRequest);
return parseToApiResponse(httpResponse);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
closeQuietly(httpResponse);
}
}
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException var2) {
}
}
private static HttpUriRequest buildRequest(Map<String, String> headers,byte[] body) {
RequestBuilder builder = RequestBuilder.create(HTTP_METHOD);
/*
* 拼接URL
* HTTP + HOST + PATH(With pathparameter) + Query Parameter
*/
try {
URIBuilder uriBuilder = new URIBuilder();
uriBuilder.setScheme("HTTP");
uriBuilder.setHost(HOST);
uriBuilder.setPath(PATH);
//增加url上参数,/get/1254131194177714180?appKey=203787616&env=PROD
uriBuilder.addParameter("appKey",APP_KEY);
uriBuilder.addParameter("env",ENV);
builder.setUri(uriBuilder.build());
} catch (URISyntaxException e) {
throw new RuntimeException("build http request uri failed", e);
}
EntityBuilder bodyBuilder = EntityBuilder.create();
bodyBuilder.setContentType(ContentType.parse("application/octet-stream; charset=utf-8"));
bodyBuilder.setBinary(body);
builder.setEntity(bodyBuilder.build());
for (Map.Entry<String, String> entry : headers.entrySet()) {
builder.addHeader(entry.getKey(), entry.getValue());
}
return builder.build();
}
private static CloseableHttpClient httpClient;
private static PoolingHttpClientConnectionManager connectionManager;
public static void init() {
SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).setSoKeepAlive(true).setSoReuseAddress(true)
.setSoTimeout(10000).build();
Registry<ConnectionSocketFactory> registry = getRegistry();
connectionManager = new PoolingHttpClientConnectionManager(registry);
connectionManager.setDefaultConnectionConfig(ConnectionConfig.custom().build());
connectionManager.setDefaultSocketConfig(socketConfig);
connectionManager.setMaxTotal(64);
connectionManager.setDefaultMaxPerRoute(5);
RequestConfig defaultConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setSocketTimeout(10000)
.setConnectionRequestTimeout(10000)
.build();
httpClient = HttpClients.custom().setConnectionManager(connectionManager).setDefaultRequestConfig(defaultConfig).build();
}
private static Registry<ConnectionSocketFactory> getRegistry() {
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
try {
registryBuilder.register("http", PlainConnectionSocketFactory.INSTANCE).build();
registryBuilder.register("https",new SSLConnectionSocketFactory(SSLContext.getDefault(), new DefaultHostnameVerifier()));
} catch (Exception e) {
throw new RuntimeException("HttpClientUtil init failure !", e);
}
return registryBuilder.build();
}
private static String parseToApiResponse(HttpResponse httpResponse) throws IOException {
System.out.println("code:"+httpResponse.getStatusLine().getStatusCode());
// message
System.out.println("message:"+httpResponse.getStatusLine().getReasonPhrase());
if(httpResponse.getEntity() != null){
// content type
Header contentType = httpResponse.getEntity().getContentType();
if(contentType != null){
System.out.println("ContentType:"+contentType.getValue());
}
else
{
System.out.println("ContentType:application/text; charset=utf-8");
}
System.out.println(httpResponse.getEntity());
// body
return new String(EntityUtils.toByteArray(httpResponse.getEntity()));
}
return null;
}
}
本文作者:积极向上的徐先生
本文链接:https://www.cnblogs.com/livebetter/p/17149232.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步