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

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

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.*;

/**
 * 签名适配
 * 

* 默认签名算法为MD5 *

* SIGN_TYPE = "MD5"; * * @author Peter Wu */ @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); } /** * @param client_id client_id * @param requestParams 请求参数 * @param timestamp timestamp * @return 签名 */ 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); } /** * @param params 请求参数 * @param client_id client_id * @param timestamp timestamp * @return 签名 */ 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()); } /** * @param requestParams 请求参数 * @param sign 签名 * @param skipAdmin 管理员是否不验证签名 * @return 签名是否正确 */ 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); } /** * @param toencrypt 待加密字符 * @param salt 盐 * @param strict 加盐是否使用严格方式,Cannot use { or } in salt.toString() * @return 加密后字符 */ protected String mergePasswordAndSalt(String toencrypt, Object salt, boolean strict) { if (toencrypt == null) { toencrypt = ""; } 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 toencrypt; } else { return toencrypt + "{" + salt.toString() + "}"; } } /** * @param client_id client_id * @return ClientSignKey */ protected abstract String loadClientSignKeyByClientId(String client_id); /** * @return request 是否有管理员权限 */ protected abstract boolean isAdmin(); }