You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Security X509证书认证的JUnit测试实现方法咨询

X509证书单元测试实现步骤

1. 前置依赖准备

JDK 原生提供 java.security.cert.CertificateFactory 可直接解析生成 X509 证书对象,无需额外依赖。如果需要快速在代码中动态生成测试用自签证书,可以引入 BouncyCastle 测试依赖:

<!-- Maven 依赖,仅测试 scope 生效 -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk18on</artifactId>
    <version>1.77</version>
    <scope>test</scope>
</dependency>

2. 构造X509Certificate测试对象

有两种常用的构造方式,可按需选择:

方式1:读取本地测试证书文件

你 Postman 测试用的证书可以导出为 .cer/.pem 格式放到项目测试资源目录,直接解析生成对象:

import java.io.FileInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

// 读取测试资源下的证书生成对象
CertificateFactory cf = CertificateFactory.getInstance("X.509");
try (FileInputStream fis = new FileInputStream("src/test/resources/test-cert.cer")) {
    X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
}

方式2:代码动态生成测试证书

无需依赖本地文件,更适合单元测试,可以自定义证书的 CN 字段值:

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;

// 注册BouncyCastle安全提供者
Security.addProvider(new BouncyCastleProvider());

// 生成RSA密钥对
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();

// 证书有效期:前后各1年,可按需调整
Date notBefore = new Date(System.currentTimeMillis() - 365 * 24 * 60 * 60 * 1000L);
Date notAfter = new Date(System.currentTimeMillis() + 365 * 24 * 60 * 60 * 1000L);

// 证书主体DN,CN设置为你要测试的目标值,比如test-user
X500Name subject = new X500Name("CN=test-user,OU=Test,O=Test Org,C=CN");
X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
        subject,
        BigInteger.valueOf(System.currentTimeMillis()),
        notBefore,
        notAfter,
        subject,
        keyPair.getPublic()
);

// 签名生成最终X509Certificate对象
X509Certificate cert = new JcaX509CertificateConverter()
        .setProvider("BC")
        .getCertificate(certBuilder.build(new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate())));

3. 编写单元测试验证提取逻辑

构造好测试证书对象后,直接传入你自定义的 Principal 提取函数,断言结果符合预期即可,JUnit5 示例如下:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class X509PrincipalExtractorTest {
    // 你自己实现的Principal提取类实例
    private final X509PrincipalExtractor extractor = new X509PrincipalExtractor();

    @Test
    void testExtractPrincipalFromCn() throws Exception {
        // 构造测试证书,CN设置为test-user
        X509Certificate testCert = generateTestCert("test-user");
        // 调用提取逻辑
        Object principal = extractor.extractPrincipal(testCert);
        // 断言结果符合预期
        assertEquals("test-user", principal.toString());
    }

    // 把动态生成证书的逻辑封装为工具方法,可传入自定义CN参数
    private X509Certificate generateTestCert(String cn) throws Exception {
        // 替换X500Name中的CN值为传入的cn参数即可
    }
}

如果你的提取逻辑包含证书有效性校验,生成测试证书时可按需调整notBefore、notAfter参数,也可以构造过期、证书链不完整的测试用例覆盖异常场景。

内容的提问来源于stack exchange,提问作者MrNobody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 09:15:07