如何在Java(Rest Assured)的API请求中添加客户端证书
解决Rest Assured请求需客户端证书的403问题
针对你遇到的客户端证书认证问题,以下提供两种对应Postman可用方式的解决方案,直接修改你的测试代码即可:
方案一:使用带密码的PFX证书文件
直接加载PFX证书并配置到Rest Assured的SSL上下文,无需额外转换格式:
package com.example.checks; import io.restassured.RestAssured; import io.restassured.config.SSLConfig; import io.restassured.response.Response; import io.restassured.specification.RequestSpecification; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.io.File; public class authorizeCustomerTests { @Test public void authorizeCustomerShouldReturn200(){ String xmlRequestBody = "xmlBodyofMyRequest"; // PFX证书路径和密码 File pfxFile = new File("path/to/your/certificate.pfx"); String pfxPassword = "123456"; RequestSpecification requestSpec = RestAssured.given() .config(RestAssured.config() .sslConfig(new SSLConfig() .keyStore(pfxFile.getAbsolutePath(), pfxPassword) .keyStoreType("PKCS12"))); // PFX默认是PKCS12格式 requestSpec.baseUri("uriOfMyService"); requestSpec.basePath("pathOfMyService"); requestSpec.header("Header1", "valueOfHeader1"); requestSpec.header("Header2", "valueOfHeader2"); requestSpec.body(xmlRequestBody); Response response = requestSpec.post(); response.prettyPrint(); Assertions.assertEquals(response.statusCode(), 200, "Check for status code"); } }
方案二:直接使用CER证书+KEY私钥(无需密码)
这种方式需要借助BouncyCastle库来加载证书和私钥,生成可用的SSL上下文:
1. 添加Maven依赖(如果用Maven)
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency>
2. 修改测试代码
package com.example.checks; import io.restassured.RestAssured; import io.restassured.config.SSLConfig; import io.restassured.response.Response; import io.restassured.specification.RequestSpecification; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.openssl.PEMParser; import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.io.FileReader; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Collections; import static io.restassured.config.SSLConfig.sslConfig; public class authorizeCustomerTests { @Test public void authorizeCustomerShouldReturn200() throws Exception { String xmlRequestBody = "xmlBodyofMyRequest"; // 证书和私钥路径 String cerPath = "path/to/your/certificate.cer"; String keyPath = "path/to/your/private.key"; // 加载CER证书 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(new FileReader(cerPath)); // 加载KEY私钥 PEMParser pemParser = new PEMParser(new FileReader(keyPath)); PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) pemParser.readObject(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); // 配置SSL上下文 SSLConfig sslConfig = sslConfig() .keyStore(privateKey, cert, Collections.emptyList()); RequestSpecification requestSpec = RestAssured.given() .config(RestAssured.config().sslConfig(sslConfig)); requestSpec.baseUri("uriOfMyService"); requestSpec.basePath("pathOfMyService"); requestSpec.header("Header1", "valueOfHeader1"); requestSpec.header("Header2", "valueOfHeader2"); requestSpec.body(xmlRequestBody); Response response = requestSpec.post(); response.prettyPrint(); Assertions.assertEquals(response.statusCode(), 200, "Check for status code"); } }
关键说明
- 两种方案都不需要提前用keytool/openssl转换格式(方案一直接用PFX,方案二直接加载CER+KEY)
- 403错误的核心原因是你的原始请求未携带客户端证书,服务端拒绝了请求
- 不要使用
relaxedHTTPSValidation(),这会跳过服务端证书校验,但不会自动添加客户端证书
内容的提问来源于stack exchange,提问作者Urman
相关产品推荐
相关产品推荐

