package cn.gistack.system.user.sync.util;
|
|
import java.util.*;
|
|
/**
|
* 计算签名工具类;
|
* 签名计算方法为:
|
*
|
* sign = MD5(自然排序(排除签名的所有参数) + [requestPath] + [requestMethod[POST|GET]] + secretKey);
|
* 注意 requestMethod 已经经过大写转换处理;
|
*/
|
public class SignBuilder {
|
public final static String TIMESTAMP_KEY = "timestamp";
|
public final static String CLIENT_ID_KEY = "clientId";
|
public final static String SIGN_KEY = "sign";
|
public final static String SALT_KEY = "salt";
|
|
private final String clientId;
|
private final String clientSecret;
|
|
private Long timestamp;
|
|
private String salt;
|
|
private String requestPath;
|
private String requestMethod;
|
|
private String sign;
|
|
private final Map<String, Object> allParam = new TreeMap<String, Object>();
|
|
|
private SignBuilder(String clientId, String clientSecret) {
|
this.clientId = clientId;
|
this.clientSecret = clientSecret;
|
}
|
|
|
public static SignBuilder create(String clientId, String clientSecret) {
|
return new SignBuilder(clientId, clientSecret);
|
}
|
|
/**
|
* 构建实例的时候 自动生成时间戳,通过 SignBuilder.getTimestamp() 获取时间戳
|
* @param clientId OAuth2.0中客户端ID 也称为 appId
|
* @param clientSecret OAuth2.0中客户端秘钥 也称为 appSecret
|
*/
|
public static SignBuilder createWithTimestampAndSalt(String clientId, String clientSecret) {
|
SignBuilder result = new SignBuilder(clientId, clientSecret);
|
return result.timestamp(System.currentTimeMillis()).salt();
|
}
|
|
|
public SignBuilder param(String key, Object value) {
|
if (sign != null) {
|
throw new RuntimeException("sign has been generated, can't change the param");
|
}
|
|
if (SIGN_KEY.equals(key)) {
|
return this;
|
}
|
|
if (TIMESTAMP_KEY.equals(key)) {
|
this.timestamp = Long.valueOf(String.valueOf(value));
|
}
|
|
if (SALT_KEY.equals(key)) {
|
this.salt = String.valueOf(value);
|
}
|
|
allParam.put(key, value);
|
return this;
|
}
|
|
public SignBuilder params(Map<String, Object> params) {
|
if (params == null) {
|
return this;
|
}
|
|
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
param(entry.getKey(), entry.getValue());
|
}
|
return this;
|
}
|
|
/**
|
* 设置时间戳
|
* @param timestamp 时间戳
|
*/
|
public SignBuilder timestamp(Long timestamp) {
|
param(TIMESTAMP_KEY, timestamp);
|
return this;
|
}
|
|
public SignBuilder requestPath(String requestPath) {
|
if (sign != null) {
|
throw new RuntimeException("sign has been generated, can't change the param");
|
}
|
this.requestPath = requestPath;
|
return this;
|
}
|
|
public SignBuilder requestMethod(String requestMethod) {
|
if (sign != null) {
|
throw new RuntimeException("sign has been generated, can't change the param");
|
}
|
if (requestMethod != null) {
|
this.requestMethod = requestMethod.toUpperCase();
|
}
|
return this;
|
}
|
|
public SignBuilder salt() {
|
return salt(Math.random());
|
}
|
|
public SignBuilder salt(Object salt) {
|
param(SALT_KEY, salt);
|
return this;
|
}
|
|
/**
|
* 获取 http 请求参数
|
*/
|
public Map<String, Object> getQueryParamMap() {
|
Map<String, Object> result = new HashMap<String, Object>(allParam);
|
result.put(SIGN_KEY, sign());
|
return result;
|
}
|
|
/**
|
* debug使用,获取签名前的原文;<br>
|
* 秘钥已脱敏,使用 <code>{clientSecret}</code> 代替
|
*/
|
public String getRawDataBeforeSign() {
|
return rawDataBeforeSign() + "{clientSecret}";
|
}
|
|
|
private String rawDataBeforeSign() {
|
allParam.put(CLIENT_ID_KEY, clientId);
|
|
if (timestamp != null && !allParam.containsKey(TIMESTAMP_KEY)) {
|
allParam.put(TIMESTAMP_KEY, timestamp);
|
}
|
|
StringBuilder sb = new StringBuilder();
|
for (Object value : allParam.values()) {
|
if (value != null) {
|
sb.append(String.valueOf(value).trim());
|
}
|
}
|
if (requestPath != null) {
|
sb.append(requestPath);
|
}
|
|
if (requestMethod != null) {
|
sb.append(requestMethod.toUpperCase());
|
}
|
|
return sb.toString();
|
}
|
|
/**
|
* 计算当前参数的签名,已经计算签名后,所有参数不可更改
|
*/
|
public String sign() {
|
if (sign != null) {
|
return sign;
|
}
|
|
this.sign = MD5Util.getMD5String(rawDataBeforeSign() + clientSecret);
|
if (this.sign == null) {
|
return "";
|
}
|
return this.sign.toUpperCase();
|
}
|
|
public String getSalt() {
|
return salt;
|
}
|
|
public String getClientId() {
|
return clientId;
|
}
|
|
public Long getTimestamp() {
|
return timestamp;
|
}
|
}
|