feat: 增加证书绝对路径实现

- 配置项增加`certAbsolutePath`字段用来定义证书的绝对路径,优先级高于`certPath`。当这两个路径都不配置时采用classpath路径`wechat/apiclient_cert.p12`。

Closes #73
This commit is contained in:
dax
2022-07-21 10:05:37 +08:00
parent af3ee97c33
commit 5ef0ff0c85
5 changed files with 29 additions and 6 deletions

View File

@@ -25,6 +25,9 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import java.util.Map;
@@ -59,8 +62,11 @@ public class WechatPayConfiguration {
v3Map.keySet().forEach(tenantId -> {
WechatPayProperties.V3 v3 = v3Map.get(tenantId);
String certPath = v3.getCertPath();
String certAbsolutePath = v3.getCertAbsolutePath();
String mchId = v3.getMchId();
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(certPath, CERT_ALIAS, mchId);
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
WechatMetaBean wechatMetaBean = keyPairFactory.initWechatMetaBean(resource, CERT_ALIAS, mchId);
wechatMetaBean.setV3(v3);
wechatMetaBean.setTenantId(tenantId);
container.addWechatMeta(tenantId, wechatMetaBean);

View File

@@ -70,6 +70,10 @@ public class WechatPayProperties {
* wechat pay certificate Path
*/
private String certPath;
/**
* wechat pay absolute certificate Path
*/
private String certAbsolutePath;
/**
* your pay server domain
*/

View File

@@ -42,6 +42,8 @@ public class WechatV2Client {
WechatPayProperties.V3 v3 = wechatMetaBean.getV3();
return model
.appSecret(v3.getAppSecret())
.certPath(v3.getCertPath())
.certAbsolutePath(v3.getCertAbsolutePath())
.request(v3.getMchId(), method, url);
}

View File

@@ -37,6 +37,8 @@ import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
@@ -97,6 +99,8 @@ public abstract class BaseModel {
@JsonIgnore
private String certPath;
@JsonIgnore
private String certAbsolutePath;
@JsonIgnore
private String signType;
public BaseModel appSecret(String appSecret) {
@@ -109,6 +113,10 @@ public abstract class BaseModel {
return this;
}
public BaseModel certAbsolutePath(String certAbsolutePath) {
this.certAbsolutePath = certAbsolutePath;
return this;
}
public BaseModel signType(String signType) {
this.signType = signType;
@@ -211,8 +219,9 @@ public abstract class BaseModel {
private RestTemplate getRestTemplateClientAuthentication(String mchId)
throws IOException, UnrecoverableKeyException, CertificateException, NoSuchAlgorithmException,
KeyStoreException, KeyManagementException {
ClassPathResource resource = new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
Resource resource = certAbsolutePath != null ? new FileSystemResource(certAbsolutePath) :
new ClassPathResource(certPath == null ? "wechat/apiclient_cert.p12" : certPath);
char[] pem = mchId.toCharArray();
KeyStore store = KeyStore.getInstance("PKCS12");

View File

@@ -21,6 +21,8 @@ package cn.felord.payment.wechat.v3;
import cn.felord.payment.PayException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import java.security.*;
import java.security.cert.X509Certificate;
@@ -30,7 +32,7 @@ import java.security.cert.X509Certificate;
*
* @author felord.cn
* @since 1.0.0.RELEASE
**/
*/
public class KeyPairFactory {
private static final KeyStore PKCS12_KEY_STORE;
@@ -47,13 +49,13 @@ public class KeyPairFactory {
/**
* 获取公私钥.
*
* @param keyPath the key path
* @param resource the resource
* @param keyAlias the key alias
* @param keyPass password
* @return the key pair
*/
public WechatMetaBean initWechatMetaBean(String keyPath, String keyAlias, String keyPass) {
ClassPathResource resource = new ClassPathResource(keyPath);
public WechatMetaBean initWechatMetaBean(Resource resource, String keyAlias, String keyPass) {
char[] pem = keyPass.toCharArray();
try {
PKCS12_KEY_STORE.load(resource.getInputStream(), pem);