package com.common.aspect; import com.common.core.utils.SignUtil; import com.common.sign.BufferedHttpServletRequest; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.servlet.HandlerMapping; import javax.servlet.http.HttpServletRequest; import java.nio.charset.StandardCharsets; import java.util.Map; /** * @author 廖振钦 * @date 2022-01-14 */ @Aspect @Component @Order(2) //优先级应该低于Log记录切面 public class SignatureAspect { private static final Logger LOGGER = LoggerFactory.getLogger(StringUtils.class); @Around("execution(* com..controller..*.*(..)) && @annotation(com.common.annotation.Sign)") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { try { this.checkSign(); return pjp.proceed(); } catch (Throwable e) { LOGGER.error("SignatureAspect>>>>>>>>", e); throw e; } } private void checkSign() throws Exception { HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); String oldSign = request.getHeader("X-SIGN"); if (StringUtils.isBlank(oldSign)) { throw new RuntimeException("取消签名Header[X-SIGN]信息"); } //获取body(对应@RequestBody) String body = null; if (request instanceof BufferedHttpServletRequest) { body = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); } //获取parameters(对应@RequestParam) Map params = null; if (!CollectionUtils.isEmpty(request.getParameterMap())) { params = request.getParameterMap(); } //获取path variable(对应@PathVariable) String[] paths = null; ServletWebRequest webRequest = new ServletWebRequest(request, null); Map uriTemplateVars = (Map) webRequest.getAttribute( HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST); if (!CollectionUtils.isEmpty(uriTemplateVars)) { paths = uriTemplateVars.values().toArray(new String[]{}); } try { String newSign = SignUtil.sign(body, params, paths); if (!newSign.equals(oldSign)) { throw new RuntimeException("签名不一致..."); } } catch (Exception e) { throw new RuntimeException("验签出错...", e); } } }