Using pac4j token request for login.gov fails using default callback filter class during OidcAuthenticator.executeTokenRequest

I am trying to use pac4j with login.gov. I have defined my security configuration.

        final OidcConfiguration oidcConfiguration = new OidcConfiguration();
        oidcConfiguration.setClientId("urn:gov:noaa:openidconnect.profiles:dashboard:sso:pmel:oap");
        oidcConfiguration.setClientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT);
        RSAPrivateKey privateKey = readPKCS8PrivateKey(new File("joe.key"));
        var privateKeyJwtConfig = new PrivateKeyJWTClientAuthnMethodConfig(JWSAlgorithm.RS256, privateKey, "logingov");
        oidcConfiguration.setPrivateKeyJWTClientAuthnMethodConfig(privateKeyJwtConfig);
        oidcConfiguration.setUseNonce(true);
        oidcConfiguration.setResponseType("code");
        oidcConfiguration.setScope("openid");
        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.setDiscoveryURI("https://idp.int.identitysandbox.gov/.well-known/openid-configuration");
        oidcConfiguration.setWithState(true);
        oidcConfiguration.setStateGenerator(new LoginGovStateGenerator());
        oidcConfiguration.setPreferredJwsAlgorithm(JWSAlgorithm.RS256);
        final OidcClient oidcClient = new OidcClient(oidcConfiguration);    
        oidcClient.setName("logingov");
        oidcClient.setSaveProfileInSession(true);
        final Clients clients = new Clients("http://localhost:8182/SimpleServer/callback", oidcClient);
        final DefaultSessionLogoutHandler defaultCasLogoutHandler = new DefaultSessionLogoutHandler();
        Config config = new Config(clients);
        defaultCasLogoutHandler.setDestroySession(true); 
        config.setSessionLogoutHandler(defaultCasLogoutHandler);
        return config

I am able to login and login.gov returns a code:

OidcCredentials(code=a3373a1b-fe76-4b3e-89e0-275dee7431d9, accessToken=null, refreshToken=null, idToken=null)

When pac4j tries to exchange the code for a token, it fails.

Client assertion Nil JSON web token, description=null, status=400
    at org.pac4j.oidc.credentials.authenticator.OidcAuthenticator.executeTokenRequest(OidcAuthenticator.java:120)

I only get to this step if I stop in the debugger and add:

client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer

to the token request.

Any examples using pac4j with login.gov? Any idea what might be missing from my config or a what I would need to do to fix the request for the token (maybe with a custom OidcAuthenticator)?

To request an access token, the OIDC client must authenticate on the /token endpoint. Generally, it’s a client_id and a client_secret.

From some other SO posts, it seems login.gov uses the private_ket_jwt for authentication. You can set that with: oidcConfig.setClientAuthenticationMethod(ClientAuthenticationMethod.PRIVATE_KEY_JWT); and oidcConfig.setPrivateKeyJWTClientAuthnMethodConfig(c);.

See: https://www.pac4j.org/docs/clients/openid-connect.html#3-advanced-configuration

Leave a Comment