mirror of
https://github.com/dromara/payment-spring-boot.git
synced 2026-03-13 21:33:41 +08:00
优化默认的证书加载,增加缓存
This commit is contained in:
@@ -23,8 +23,10 @@ import lombok.AllArgsConstructor;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -39,27 +41,32 @@ import java.util.stream.Collectors;
|
||||
public class InMemoryWechatTenantService implements WechatTenantService {
|
||||
private final WechatPayProperties wechatPayProperties;
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final Set<WechatMetaBean> cache = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public Set<WechatMetaBean> loadTenants() {
|
||||
Map<String, WechatPayProperties.V3> v3Map = wechatPayProperties.getV3();
|
||||
KeyPairFactory keyPairFactory = new KeyPairFactory();
|
||||
return v3Map.entrySet()
|
||||
.stream()
|
||||
.map(entry -> {
|
||||
WechatPayProperties.V3 v3 = entry.getValue();
|
||||
String tenantId = entry.getKey();
|
||||
String certPath = v3.getCertPath();
|
||||
String certAbsolutePath = v3.getCertAbsolutePath();
|
||||
String mchId = v3.getMchId();
|
||||
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
|
||||
resourceLoader.getResource(certPath == null ? "classpath:wechat/apiclient_cert.p12" :
|
||||
certPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? certPath : ResourceUtils.CLASSPATH_URL_PREFIX + certPath);
|
||||
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, mchId);
|
||||
wechatMetaBean.setV3(v3);
|
||||
wechatMetaBean.setTenantId(tenantId);
|
||||
return wechatMetaBean;
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
if (CollectionUtils.isEmpty(cache)) {
|
||||
Map<String, WechatPayProperties.V3> v3Map = wechatPayProperties.getV3();
|
||||
KeyPairFactory keyPairFactory = new KeyPairFactory();
|
||||
Set<WechatMetaBean> beans = v3Map.entrySet()
|
||||
.stream()
|
||||
.map(entry -> {
|
||||
WechatPayProperties.V3 v3 = entry.getValue();
|
||||
String tenantId = entry.getKey();
|
||||
String certPath = v3.getCertPath();
|
||||
String certAbsolutePath = v3.getCertAbsolutePath();
|
||||
String mchId = v3.getMchId();
|
||||
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
|
||||
resourceLoader.getResource(certPath == null ? "classpath:wechat/apiclient_cert.p12" :
|
||||
certPath.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX) ? certPath : ResourceUtils.CLASSPATH_URL_PREFIX + certPath);
|
||||
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, mchId);
|
||||
wechatMetaBean.setV3(v3);
|
||||
wechatMetaBean.setTenantId(tenantId);
|
||||
return wechatMetaBean;
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
cache.addAll(beans);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,11 +27,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
||||
import org.springframework.util.AlternativeJdkIdGenerator;
|
||||
@@ -54,8 +50,7 @@ import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -135,7 +130,7 @@ public class SignatureProvider {
|
||||
@SneakyThrows
|
||||
public String requestSign(String tenantId, String method, String canonicalUrl, String body) {
|
||||
|
||||
long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
|
||||
long timestamp = Instant.now().getEpochSecond();
|
||||
String nonceStr = nonceStrGenerator.generateId()
|
||||
.toString()
|
||||
.replaceAll("-", "");
|
||||
@@ -175,7 +170,6 @@ public class SignatureProvider {
|
||||
* @param params the params
|
||||
* @return the boolean
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean responseSignVerify(ResponseSignVerifyParams params) {
|
||||
|
||||
String wechatpaySerial = params.getWechatpaySerial();
|
||||
@@ -190,13 +184,15 @@ public class SignatureProvider {
|
||||
.orElseThrow(() -> new PayException("cannot obtain the certificate"));
|
||||
});
|
||||
|
||||
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initVerify(certificate.getX509Certificate());
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
try {
|
||||
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
|
||||
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
|
||||
signer.initVerify(certificate.getX509Certificate());
|
||||
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
|
||||
return signer.verify(Base64Utils.decodeFromString(params.getWechatpaySignature()));
|
||||
}catch (Exception e){
|
||||
throw new PayException("An exception occurred during the response verification, the cause: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,9 +20,12 @@ package cn.felord.payment.wechat.v3;
|
||||
import cn.felord.payment.wechat.WechatTenantService;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 配置容器
|
||||
@@ -33,7 +36,6 @@ import java.util.concurrent.ConcurrentSkipListSet;
|
||||
@AllArgsConstructor
|
||||
public class WechatMetaContainer {
|
||||
private final Map<String, WechatMetaBean> wechatMetaBeanMap = new ConcurrentHashMap<>();
|
||||
private final Set<String> tenantIds = new ConcurrentSkipListSet<>();
|
||||
private final WechatTenantService wechatTenantService;
|
||||
|
||||
/**
|
||||
@@ -47,22 +49,9 @@ public class WechatMetaContainer {
|
||||
|
||||
private void addMeta(WechatMetaBean wechatMetaBean) {
|
||||
String tenantId = wechatMetaBean.getTenantId();
|
||||
tenantIds.add(tenantId);
|
||||
wechatMetaBeanMap.put(tenantId, wechatMetaBean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove wechat meta wechat meta bean.
|
||||
*
|
||||
* @param tenantId the tenantId
|
||||
* @return the wechat meta bean
|
||||
*/
|
||||
public WechatMetaBean removeWechatMeta(String tenantId) {
|
||||
tenantIds.remove(tenantId);
|
||||
return this.wechatMetaBeanMap.remove(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets wechat meta.
|
||||
*
|
||||
@@ -86,6 +75,9 @@ public class WechatMetaContainer {
|
||||
* @return the properties keys
|
||||
*/
|
||||
public Set<String> getTenantIds() {
|
||||
return tenantIds;
|
||||
return wechatTenantService.loadTenants()
|
||||
.stream()
|
||||
.map(WechatMetaBean::getTenantId)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user