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

使用com.nimbusds.jose验证Azure AD JWT时遇PKIX路径构建失败

使用com.nimbusds.jose验证JWT时的PKIX证书路径错误问题

报错信息

com.nimbusds.jose.RemoteKeySourceException: Couldn't retrieve remote JWK set: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

实现代码

try {
    ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
    JWKSource keySource = null;
    try {
      ResourceRetriever jwkRetriever = new DefaultResourceRetriever(100000, 100000);
      JWKSetCache jwkSetCache = new DefaultJWKSetCache(1440,
          1430, TimeUnit.MINUTES);
      keySource = new RemoteJWKSet(new URL(
          "https://login.windows.net/36799f34-92fd-4612-8473-80173f2406e8/discovery/v2.0/keys"),jwkRetriever,jwkSetCache);
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
    JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg,keySource);
    jwtProcessor.setJWSKeySelector(keySelector);

    JWTClaimsSet claimsSet = null;
    SecurityContext ctx = null; // optional context parameter, not required here
    try {
      claimsSet = jwtProcessor.process(token, ctx);
    } catch (ParseException e) {
      e.printStackTrace();
    } catch (BadJOSEException e) {
      e.printStackTrace();
    } catch (JOSEException e) {
      e.printStackTrace();
    }

已配置的信任库信息(application.properties)

trust.store=myapp_dev.p12
trust.store.password=changeit

疑问

我已经将证书添加到信任库,但仍出现上述错误,请问哪里操作有误?


可能的原因及解决方法

1. Spring配置未被DefaultResourceRetriever识别

DefaultResourceRetriever默认使用JVM自带的信任库,不会自动读取Spring配置的trust.store。需要手动加载自定义信任库并构建SSLContext,传给DefaultResourceRetriever:

// 加载自定义PKCS12信任库
KeyStore trustStore = KeyStore.getInstance("PKCS12");
try (InputStream is = new FileInputStream("myapp_dev.p12")) {
    trustStore.load(is, "changeit".toCharArray());
}

// 初始化信任管理器并构建SSLContext
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);

// 给ResourceRetriever设置自定义SSLContext
DefaultResourceRetriever jwkRetriever = new DefaultResourceRetriever(100000, 100000);
jwkRetriever.setSSLContext(sslContext);

2. 证书导入不规范

  • 确认导入的是Microsoft授权服务器的根证书/中间证书链,而非客户端证书;
  • 用命令检查p12文件是否包含完整证书链:
    keytool -list -v -keystore myapp_dev.p12 -storetype PKCS12
    
  • 重新导入证书时使用正确命令:
    keytool -importcert -file microsoft_root_cert.cer -keystore myapp_dev.p12 -storetype PKCS12 -alias microsoft_root
    

3. 信任库路径配置错误

  • 确认trust.store的路径是绝对路径,或相对于项目运行工作目录的路径;可通过System.getProperty("user.dir")打印当前工作目录验证文件是否存在;
  • 若信任库放在类路径下,可直接通过类加载器读取:
    InputStream is = getClass().getResourceAsStream("/myapp_dev.p12");
    

4. 未通过JVM参数指定信任库

若不想在代码中手动加载SSLContext,可通过JVM启动参数强制指定自定义信任库:

-Djavax.net.ssl.trustStore=myapp_dev.p12 -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=PKCS12

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:21:34