package com.fdkankan.cloud.acl.aop; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fdkankan.cloud.acl.entity.AppConfig; import com.fdkankan.cloud.acl.entity.AppKeyConfig; import com.fdkankan.cloud.acl.service.IAppConfigService; import com.fdkankan.cloud.acl.service.IAppKeyConfigService; import com.fdkankan.common.constant.ErrorCode; import com.fdkankan.common.exception.BusinessException; import com.fdkankan.common.util.RsaUtil; import com.mybatisflex.core.query.QueryWrapper; import lombok.extern.log4j.Log4j2; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.crypto.Cipher; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Instant; import java.util.Objects; @Log4j2 @Aspect @Component @Order(101) public class CheckSignatureAspect { @Autowired private IAppConfigService appConfigService; @Autowired private IAppKeyConfigService appKeyConfigService; @Pointcut("@annotation(com.fdkankan.cloud.acl.annotation.CheckSignature)") public void CheckSignature() { } @Before("CheckSignature()") public void doBefore(JoinPoint joinPoint) throws Exception { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String signature = request.getHeader("signature"); if(StrUtil.isEmpty(signature)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "signature cannot be empty"); } String appCode = request.getParameter("appCode"); if(StrUtil.isEmpty(appCode)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "appCode cannot be empty"); } String timestamp = request.getParameter("timestamp"); if(StrUtil.isEmpty(timestamp)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "timestamp cannot be empty"); } //时间戳有效时间是15分钟 Instant now = Instant.now(); long epochSecond = now.getEpochSecond(); long expiraSecond = Long.valueOf(timestamp) + 15 * 60L; if(expiraSecond < epochSecond){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "signature expired"); } AppConfig appConfig = appConfigService.getByAppCode(appCode); if(Objects.isNull(appConfig)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003); } AppKeyConfig appKeyConfig = appKeyConfigService.getByAppConfigId(appConfig.getId()); if(Objects.isNull(appKeyConfig)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003); } signature = RsaUtil.create(appKeyConfig.getPrivateKey(), null).decryptByPrivateKey(signature); log.info("解密:{}", signature); String[] split = signature.split("-"); if(split.length != 2){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "signature mismatch"); } String signatureAppCode = split[0]; String signatureTimestamp = split[1]; if(!appCode.equals(signatureAppCode) || !timestamp.equals(signatureTimestamp)){ throw new BusinessException(ErrorCode.FAILURE_CODE_3003.code(), "signature mismatch"); } } public static void main(String[] args) { String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHmJkGNg0N0tKroJAbqdO6ndgdEgJBnClW3KhzUCQSLVYhBvewjlXRmc1KQbI7QHpcdbuhvGT/RVVu4npVRPnQilGSyOxLbDI4TKaM6ZMSYQ1RS5vTj2HbvJ2s21AjEhhRcDYvSEDs4KsZaOmta/Cfok8jfG46o3UB6LkwzCMHtQIDAQAB"; String test = "af9c663f3fd744c6bf40dbcd1c9aada3-" + "1719890259"; String s = RsaUtil.create(null, publicKey).encryptByPublicKey(test); System.out.println(s); } }