All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.bestwu.api.sign.ApiSignAdpter Maven / Gradle / Ivy

There is a newer version: 1.2.4
Show newest version
package cn.bestwu.api.sign;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.*;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * SIGN_TYPE = "MD5";
 */
@Slf4j
public abstract class ApiSignAdpter {

	/**
	 * @param client_id     client_id
	 * @param requestParams 请求参数
	 * @param timestamp     timestamp
	 * @return 请求签名
	 */
	public String sign(Map requestParams, String client_id, String timestamp) {
		Map params = new HashMap<>();
		for (String name : requestParams.keySet()) {
			String[] values = requestParams.get(name);
			String valueStr = "";
			int length = values.length;
			for (int i = 0; i < length; i++) {
				valueStr = (i == length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}
			params.put(name, valueStr);
		}

		return getSign(params, client_id, timestamp);
	}

	public String sign(MultiValueMap requestParams, String client_id, String timestamp) {
		Map params = new HashMap<>();
		for (String name : requestParams.keySet()) {
			List values = requestParams.get(name);
			String valueStr = "";
			int length = values.size();
			for (int i = 0; i < length; i++) {
				valueStr = (i == length - 1) ? valueStr + values.get(i) : valueStr + values.get(i) + ",";
			}
			params.put(name, valueStr);
		}

		return getSign(params, client_id, timestamp);
	}

	protected String getSign(Map params, String client_id, String timestamp) {
		Assert.hasText(client_id);
		Assert.hasText(timestamp);

		List keys = new ArrayList<>(params.keySet());
		Collections.sort(keys);

		String prestr = "";

		for (String key : keys) {
			String value = params.get(key);
			if (value == null || value.equals("") || key.equalsIgnoreCase("sign")
					|| key.equalsIgnoreCase("sign_type")) {
				continue;
			}
			try {
				prestr = prestr + key + "=" + URLEncoder.encode(value, "UTF-8") + "&";
			} catch (UnsupportedEncodingException ignored) {
				//			never throw
			}
		}
		prestr += client_id + "&" + timestamp;
		if (log.isDebugEnabled()) {
			log.debug("待签名参数字符串:" + prestr);
		}
		prestr = mergePasswordAndSalt(prestr, loadClientSignKeyByClientId(client_id), false);
		return Base64Utils.encodeToString((client_id + ":" + timestamp + ":" + DigestUtils.md5DigestAsHex(prestr.getBytes())).getBytes());
	}

	public boolean isSign(Map requestParams, String sign, boolean skipAdmin) {
		if (skipAdmin && isAdmin()) {
			return true;
		}

		if (!StringUtils.hasText(sign)) {
			return false;
		}
		String[] strings = new String(Base64Utils.decodeFromString(sign)).split(":");
		if (strings.length != 3) {
			return false;
		}
		String client_id = strings[0];
		String timestamp = strings[1];
		if (!StringUtils.hasText(client_id)) {
			return false;
		}
		if (!StringUtils.hasText(timestamp)) {
			return false;
		}
		if (Math.abs(System.currentTimeMillis() - Long.parseLong(timestamp)) > 10 * 60 * 1000) {
			return false;
		}
		String serviceSign = sign(requestParams, client_id, timestamp);
		if (log.isDebugEnabled()) {
			log.debug("服务端签名:" + serviceSign);
		}
		return sign.equals(serviceSign);
	}

	protected String mergePasswordAndSalt(String password, Object salt, boolean strict) {
		if (password == null) {
			password = "";
		}

		if (strict && (salt != null)) {
			if ((salt.toString().lastIndexOf("{") != -1)
					|| (salt.toString().lastIndexOf("}") != -1)) {
				throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
			}
		}

		if ((salt == null) || "".equals(salt)) {
			return password;
		} else {
			return password + "{" + salt.toString() + "}";
		}
	}

	protected abstract String loadClientSignKeyByClientId(String client_id);

	protected abstract boolean isAdmin();
}