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

使用pac4j向login.gov请求令牌失败:client_assertion含null的iat声明

问题

我尝试使用pac4j oidc-client对接login.gov进行认证,相关安全配置如下:

oidcConfiguration.setDiscoveryURI("https://idp.int.identitysandbox.gov/.well-known/openid-configuration");
oidcConfiguration.setClientId(clientId);
oidcConfiguration.setUseNonce(true);
oidcConfiguration.setResponseType("code");
oidcConfiguration.setScope("openid");
// Load private key from PEM file
ClassLoader classLoader = getClass().getClassLoader();
File pkFile = new File(classLoader.getResource("private.pem").getFile());
var privateKey = readPKCS8PrivateKey(pkFile);
var privateKeyJwtConfig = new PrivateKeyJWTClientAuthnMethodConfig(JWSAlgorithm.RS256, privateKey);
oidcConfiguration.setPrivateKeyJWTClientAuthnMethodConfig(privateKeyJwtConfig);
oidcConfiguration.addCustomParam("acr_values", "http://idmanagement.gov/ns/assurance/ial/1");
oidcConfiguration.addCustomParam("prompt", "select_account");
oidcConfiguration.addCustomParam("client_assertion_type","urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
oidcConfiguration.setClientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT);
oidcConfiguration.setStateGenerator(new RandomValueGenerator(28));
oidcConfiguration.setWithState(true);
oidcConfiguration.setPreferredJwsAlgorithm(JWSAlgorithm.RS256);
oidcConfiguration.setSecret("bogus");

注:即使login.gov配置中未设置密钥,设置一个secret才能让发送到令牌端点的请求包含client_assertion。

pac4j发送的client_assertion负载中包含null的iat声明,导致令牌端点返回错误并抛出异常:

JEE PAC4J DEMO 17:53:54.491 [qtp1990828041-45] DEBUG o.p.core.engine.DefaultCallbackLogic - extracted credentials: OidcCredentials(code=e45f8b5b-d039-4c0d-9c75-f6251568fb80, accessToken=null, refreshToken=null, idToken=null)
[WARNING] /callback
org.pac4j.oidc.exceptions.OidcTokenException: Bad token response, error=Client assertion iat must be an integer or floating point Unix timestamp representing a time in the past, description=null, status=400
    at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.executeTokenRequest(OidcAuthenticator.java:120)
    at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.validate(OidcAuthenticator.java:65)
    at org.pac4j.core.client.BaseClient.internalValidateCredentials(BaseClient.java:113)
    at org.pac4j.core.client.BaseClient.validateCredentials(BaseClient.java:95)
    at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:83)
    at org.pac4j.jee.filter.CallbackFilter.internalFilter(CallbackFilter.java:63)
    at org.pac4j.jee.config.AbstractConfigFilter.doFilter(AbstractConfigFilter.java:92)
    at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:210)
    at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
    at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170)

pac4j发送的client_assertion负载如下,其中iat声明为null:

{
  "sub": "urn:gov:gsa:openidconnect.profiles:sp:sso:doi:quicktime_9996",
  "aud": "https://idp.int.identitysandbox.gov/api/openid_connect/token",
  "nbf": null,
  "iss": "urn:gov:gsa:openidconnect.profiles:sp:sso:doi:quicktime_9996",
  "exp": 1717804013,
  "iat": null,
  "jti": "mspXEErL5LUDuO-x5IUmTYDB679lA0TyYPYIT6d2_xg"
}

如何让pac4j生成的iat声明为当前系统时间戳而非null?

解决方案

为PrivateKeyJWTClientAuthnMethodConfig配置自定义JWT生成器,强制生成iat声明:

  1. 创建DefaultJwtGenerator实例并开启iat声明生成
  2. 将生成器绑定到私钥JWT认证配置中

修改后的关键代码如下:

// 加载私钥逻辑保持不变
ClassLoader classLoader = getClass().getClassLoader();
File pkFile = new File(classLoader.getResource("private.pem").getFile());
var privateKey = readPKCS8PrivateKey(pkFile);

// 配置JWT生成器,强制包含iat声明
DefaultJwtGenerator jwtGenerator = new DefaultJwtGenerator();
jwtGenerator.setIncludeIssuedAt(true); // 开启iat生成
jwtGenerator.setIncludeNotBefore(true); // 可选,若需要生成nbf声明

// 绑定生成器到私钥认证配置
var privateKeyJwtConfig = new PrivateKeyJWTClientAuthnMethodConfig(JWSAlgorithm.RS256, privateKey);
privateKeyJwtConfig.setJwtGenerator(jwtGenerator);

// 后续配置保持不变
oidcConfiguration.setPrivateKeyJWTClientAuthnMethodConfig(privateKeyJwtConfig);
// ... 其他原有配置

另外,若使用的pac4j版本较旧,升级至最新稳定版也可能解决默认不生成iat的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:05:56