实现
要实现参数验签, 首先需要提取出请求参数, 这里无论 GET 还是 POST 请求, 我们都将参数提取出来放在map中处理
提取参数并排序
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
| package cn.idea360.demo.modules.sign;
import com.alibaba.fastjson.JSONObject; import org.springframework.http.HttpMethod;
import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.stream.Collectors;
public class RequestUtils {
public static Map<String, String> getUrlParams(HttpServletRequest request) {
String param = ""; try { param = URLDecoder.decode(request.getQueryString(), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } Map<String, String> result = new HashMap<>(16); String[] params = param.split("&"); for (String s : params) { int index = s.indexOf("="); result.put(s.substring(0, index), s.substring(index + 1)); } return result; }
public static Map<String, String> getBodyParams (HttpServletRequest request) throws IOException { String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator())); return JSONObject.parseObject(body, Map.class); }
public static SortedMap<String, String> getAllParams(HttpServletRequest request) throws IOException {
SortedMap<String, String> sortedParams = new TreeMap<>();
Map<String, String> urlParams = getUrlParams(request); for (Map.Entry entry : urlParams.entrySet()) { sortedParams.put((String) entry.getKey(), (String) entry.getValue()); }
if (!HttpMethod.GET.name().equals(request.getMethod())) { Map<String, String> bodyParams = getBodyParams(request); if (null != bodyParams) { for (Map.Entry entry : bodyParams.entrySet()) { sortedParams.put((String) entry.getKey(), (String) entry.getValue()); } } } return sortedParams; } }
|
参数验签
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
| package cn.idea360.demo.modules.sign;
import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.util.DigestUtils;
import java.util.*;
@Slf4j public class SignUtils {
public static String getParamsSign(SortedMap<String, String> params) {
params.remove("sign"); String paramsJsonStr = JSONObject.toJSONString(params);
String md5 = DigestUtils.md5DigestAsHex(paramsJsonStr.getBytes()).toUpperCase(); log.info("加签参数: {}, md5摘要: {}", paramsJsonStr, md5);
return md5; }
public static boolean verifySign(SortedMap<String, String> params) {
String urlSign = params.get("sign"); log.info("Url Sign : {}", urlSign);
if (StringUtils.isBlank(urlSign)) { return false; }
String paramsSign = getParamsSign(params); log.info("Param Sign : {}", paramsSign);
return StringUtils.isNotBlank(paramsSign) && urlSign.equals(paramsSign); } }
|
AOP实现
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
|
@Slf4j @Aspect @Component public class SignAspect {
@Pointcut("@annotation(com.idea360.auth.common.annotation.Sign)") public void signPointCut() { }
@Before("signPointCut()") public void doBefore(JoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs(); String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
Map<String, String> unSortedMap = new HashMap<>(); for (int i = 0; i < args.length; i++) { if (args[i] instanceof ServletRequest || args[i] instanceof ServletResponse) { continue; } String json = GsonUtils.toJson(args[i]); if (GsonUtils.isJSON(json)) { Map<String, String> map = GsonUtils.fromJson(json, Map.class); unSortedMap.putAll(map); } else { unSortedMap.put(argNames[i], String.valueOf(args[i])); } } SortedMap<String, String> sortedMap = new TreeMap<>(unSortedMap); log.info("参数验签, request params: [{}]", sortedMap.toString());
if (!SignUtils.verifySign(sortedMap)) { throw new RuntimeException("非法请求"); } } }
|
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
| public class GsonUtils {
private static final Gson gson = new Gson();
public static boolean isJSON(String jsonStr) { JsonElement jsonElement; try { jsonElement = JsonParser.parseString(jsonStr); } catch (Exception e) { return false; } if (jsonElement == null) { return false; } if (!jsonElement.isJsonObject()) { return false; } return true; }
public static boolean isJSONObject(Object o) { try { String json = gson.toJson(o); return isJSON(json); } catch(com.google.gson.JsonSyntaxException ex) { return false; } }
public static String toJson(Object o) { return gson.toJson(o); }
public static <T> T fromJson(String json, Class<T> clz) { return gson.fromJson(json, clz); } }
|
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。