test: 添加证书编号

main
13009 2024-06-18 18:01:45 +08:00
parent 23d682431d
commit b9d0eb3b4d
9 changed files with 93 additions and 14 deletions

View File

@ -32,5 +32,18 @@
<artifactId>httpclient5</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -22,4 +22,9 @@ public interface CertificateProvider {
* @return X.509
*/
X509Certificate getAvailableCertificate();
/**
*
*/
boolean isAvailableCertificate(String serialNumber);
}

View File

@ -46,6 +46,16 @@ public final class DefaultValidator implements Validator {
validateResponseSignature(response, channel);
}
@Override
public void validate(HttpRequest newRequest) {
// 校验证书
CertificateProvider provider = getProfile().getSignature().getCertificateProvider();
Signer signer = getProfile().getSignature().getSigner();
if (!provider.isAvailableCertificate(signer.getCertificateSerial())) {
throw new ValidationException(String.format("证书已失效, 序列号:%s", signer.getCertificateSerial()));
}
}
public void isInvalidHttpCode(OriginalResponse response) {
if (response.getStatusCode() < HTTP_OK || response.getStatusCode() >= HTTP_MULT_CHOICE) {
throw new ValidationException(String.format("校验失败, HttpStatusCode=%s, Request-Id=%s, HttpResponseBody=%s",

View File

@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import static com.czcb.scfs.api.core.util.Strings.timeRange;
@ -24,12 +25,10 @@ public final class LocalCertificateProvider implements CertificateProvider {
private X509Certificate availableCertificate;
public LocalCertificateProvider(List<X509Certificate> certificates) {
if (certificates.isEmpty()) {
throw new IllegalArgumentException("The parameter list of constructor is empty.");
}
if (certificates != null && !certificates.isEmpty()) {
certificates.forEach(this::addX509Certificate);
}
}
/**
*
@ -44,8 +43,9 @@ public final class LocalCertificateProvider implements CertificateProvider {
public void addX509Certificate(X509Certificate certificate) {
if (!validity.withinValidity(certificate)) {
logger.error("证书已失效, 序列号:{}, 有效范围:[{}]", toHexUpper(certificate.getSerialNumber()), timeRange(certificate));
return;
String serialNumberHexUpper = toHexUpper(certificate.getSerialNumber());
String timeRange = timeRange(certificate);
logger.error("证书已失效, 序列号:{}, 有效期:[{}]", serialNumberHexUpper, timeRange);
}
certificates.put(toHexUpper(certificate.getSerialNumber()), certificate);
@ -62,10 +62,12 @@ public final class LocalCertificateProvider implements CertificateProvider {
availableCertificate = validity.getLongestCertificate(certificates);
}
if (availableCertificate == null) {
throw new IllegalArgumentException("没有有效的证书");
}
return availableCertificate;
}
@Override
public boolean isAvailableCertificate(String serialNumber) {
X509Certificate certificate = getCertificate(serialNumber);
return Objects.nonNull(certificate) && validity.withinValidity(certificate);
}
}

View File

@ -53,6 +53,9 @@ public abstract class AbstractApiClient implements ApiClient {
public <T> HttpResponse<T> exchange(HttpRequest request, Class<T> responseClass) {
// 组装请求对象
HttpRequest newRequest = assembleRequest(request);
// 请求校验
validateRequest(newRequest);
// 打印请求数据
httpLogger.logRequest(newRequest, getHttpVersion());
@ -155,6 +158,10 @@ public abstract class AbstractApiClient implements ApiClient {
return credential.buildRequestAuthorization(request, channel);
}
private void validateRequest(HttpRequest newRequest) {
validator.validate(newRequest);
}
/**
*
*

View File

@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIDeTCCAmGgAwIBAgIhAII88+MQ8uLtGvhVBudKldxDAQBv3vL9AZlT+vTeEqi/MA0GCSqGSIb3
DQEBCwUAMIGNMQswCQYDVQQGEwJDTjESMBAGA1UECAwJ5rWZ5rGf55yBMRIwEAYDVQQHDAnmna3l
t57luIIxITAfBgNVBAoMGOa1meaxn+eooOW3nuWVhuS4mumTtuihjDEYMBYGA1UECwwP5pWw5a2X
6YeR6J6N6YOoMRkwFwYDVQQDDBBzY2ZzLmN6Y2IuY29tLmNuMB4XDTIzMDYxODA5MDczMVoXDTI0
MDYxODA5MDczMVowUjELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCea1meaxn+ecgTESMBAGA1UEBwwJ
5p2t5bee5biCMRswGQYDVQQKDBLnqKDlt57llYbkuJrpk7booYwwggEiMA0GCSqGSIb3DQEBAQUA
A4IBDwAwggEKAoIBAQCfHOgnUYbFi780EX9xQTdWPvCyBhaEnU5Y2p1bW4dHoumgEtjQOkLlRe3U
g1lu6TfhuE9YOQ9+V+Dsnzt7MXIRI7KlOuwpfwXn3e/MYP5ZtDBUiuSGNNVSP39wgb6aYXhvFY/L
m9gaO8Q4rauzK94Clw4sH3a7J6ST50xHss8VjSVFUkcPhpH+OJBTUrXWiccZCn01XDz0vmq6J3Au
jM55WBEmoz2r9iiVdCjZsgB4veQIpCKuMvJsEXVgRzULUnaqdX+7BTDBs30kCGyyBarR+wXLAKNQ
1nENFs1IGM99I+O8UsD6CvUnt2t7l3B8/qIlOSfds8x+BoUxQwhmUaMjAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBACRCHOYH8ncOiYjMm3As7OFdnVDuGByMoZsDucqwrs0mJZVdp3OMgvGhC9zkzdZX
sJFKQeIRp/13cD1SKxtwfU7w4J+/FWpWPEG9Jf2bLqurYivu0tTa1xe5SDL4unNaj/o7BA0vaKJe
gagyULAilNCGBCfy59BSR/GQbgAC6pdl3soMx/s1c9BcZVplbq12/rmStGce6h3QqNjwpRMowbVW
XswXhr08AUevF7UriDjHkCsa6MqQ5x+ShV9qO1f2LDYBQRnM2Ty44EV5eUbHyKOJAYF+WqT6IRiA
2sMZrKRTHaNZB4j0Vc87HuxDtTNh/EEXU2sO31WZHs3ymAChbC4=
-----END CERTIFICATE-----

View File

@ -0,0 +1,24 @@
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfHOgnUYbFi780EX9xQTdWPvCy
BhaEnU5Y2p1bW4dHoumgEtjQOkLlRe3Ug1lu6TfhuE9YOQ9+V+Dsnzt7MXIRI7KlOuwpfwXn3e/M
YP5ZtDBUiuSGNNVSP39wgb6aYXhvFY/Lm9gaO8Q4rauzK94Clw4sH3a7J6ST50xHss8VjSVFUkcP
hpH+OJBTUrXWiccZCn01XDz0vmq6J3AujM55WBEmoz2r9iiVdCjZsgB4veQIpCKuMvJsEXVgRzUL
UnaqdX+7BTDBs30kCGyyBarR+wXLAKNQ1nENFs1IGM99I+O8UsD6CvUnt2t7l3B8/qIlOSfds8x+
BoUxQwhmUaMjAgMBAAECggEAQ+meKz4QdJvnse0wBKKN4Hl/2bRggxzzVliFJnvEG27tIb45nXLo
n5x/3R9tGjpf+C9namP8eXQ/1C9Iv5XEto0SkJS8PR/y4NspIYZaueX/ZO5diOzfCjqBBf/S32jv
8xX0aLbtf5D3+SsjaJe2LEvWKD4Luuk6RUjJlaa73dnSuGFSuvYV8MvFdHtfU8L8ZRoqZwmM9QTg
+Gpix4z6Hy/Mmi1xRl0EhIITq+mV9wR9Ock/0o12nvsNDyDSyrrt3niXTTkVCbct+t4UFwtnrZyH
dwl1OQ+WleTkUQY+wNgpq4jLjwGowXnqXlKff3tvXEt+3tpdOS8i+kXYwIrvIQKBgQDVnldDo2iq
TwLcZjXbreHskn/4hvWYUPqucEZ93jmyYNKUKPlXkVnc+kXnS0uuM5JZpi/7+FDkTqwHK83ET4/n
kTC9zM+K7KyIBbljclPjzXYJAW7nwD8A/vKx6CWi++f4buYc+lttsTprdAZ4/kWPTnvNJSjhSTAR
SQ32HxkiIQKBgQC+rjujW31WN4d2j48+K0B+7bIQON+VtmBZ48u2ZIQOi4PdoBvHv8HqQyhJlR+6
z49k5WczSqAXdG2+nIgs8fpjj0lc7YiMIYs0VsLodOToH9J2MfXjWi+A4Y2vbfcjfUuCWhKSZs6B
eMLNe1LPIBDmlT3A1X83qkCpvAYYQWAkwwKBgFVtslZRZk0dtfYwRf+phT1XxSe9yT/1uprCOd6i
XY6RnAU2cajsbvSpfgUmnoh3BWMmy+/HeYokUDW59ds5OkKQVN7CpolXZxQqvd4gXZ4vj7HASfsS
bd/XFXXCcjLA7R70MsCJ+sBebQ+F4gTHI0hRSb9bygJ2g2uWPKgd/a4hAoGABCtZIHxKpEz4iE4h
SrG1alEWOKaVtPdU6gJCHQ3bmVnRm1H56Yc23UF0qw84r2QEdadSd1ulXn3sPGO90oXD/NNQPljv
SGkfWxiekGil7LFtb6ot/zeknEPSTkiwQ7VkpkgD6fGXiFs0nzuYFvFTjUcsH4BLlNMDMPLsizE6
wfMCgYANvw4Lq1cVfHAl3f6IZlpWHPFEEJbPcBLu9+qtUlZjleCaWA8WXuiBxkqaIkeVi3JMst34
adfIfBsAk4FeyLpkiTYNjOckZvXFXYKA3a05l/RJ5rsnnI9GRh+3Gk3V+87OU7HwMU6jNZmQiPIO
/jerEvZ9A5tbuzKkfJj2F0ZXfw==
-----END PRIVATE KEY-----