quarkus-oidc

How to configure quarkus to login to salesforce using JWT as authorisation


I admit to being confused by all of the options in OIDC.

I have a quarkus application that I want to use to login to salesforce using a JWT as the bearer token.

There was a request for this to be supported Support Salesforce oauth_jwt_flow and a fix was developed OIDC client support for using JWTs as Authorization Grants but I can't figure out the set of oidc related properties that I need to provide to get it working as intended.

I have something working but it doesn't feel like it is the correct way.

with application.properties

quarkus.oidc-client.auth-server-url=https://test.salesforce.com
quarkus.oidc-client.discovery-enabled=false
quarkus.oidc-client.token-path=/services/oauth2/token
quarkus.oidc-client.client-id=XXXXXX
quarkus.oidc-client.grant.type=jwt
#quarkus.oidc-client.credentials.jwt.source=bearer
quarkus.oidc-client.credentials.jwt.lifespan=3600
quarkus.oidc-client.credentials.jwt.key=-----BEGIN PRIVATE KEY-----\
\nXXXX\
\n-----END PRIVATE KEY-----
quarkus.oidc-client.credentials.jwt.audience=https://test.salesforce.com

smallrye.jwt.sign.key=-----BEGIN PRIVATE KEY-----\
\nXXXXXX\
\n-----END PRIVATE KEY-----

I can obtain the access token by calling String accessToken = getAccessToken().await().indefinitely();

    public String generateJwt() {
        Map<String, Object> claims = new HashMap<>();
        claims.put("sub", "XXXXXX");
        claims.put("aud", "https://test.salesforce.com");
        claims.put("iss", "XXXXXX");
        claims.put("exp", System.currentTimeMillis() / 1000 + 3600);

        return Jwt.claims(claims)
                .jws()
                .sign();
    }


    public Uni<String> getAccessToken() {
        Map<String, String> params = new HashMap<>();
        params.put("assertion", generateJwt());
        return oidcClient.getTokens(params)
                .onItem().transform(Tokens::getAccessToken);
    }

However, I have to provide the private key twice (quarkus.oidc-client.credentials.jwt.key and smallrye.jwt.sign.key and I have provide the client id (in the claims as 'sub') when it can be specified in the properties as quarkus.oidc-client.client-id

Is there a correct way of doing this via configuration?


Solution

  • Managed to find it.
    I had to add quarkus.oidc-client.credentials.jwt.assertion=true and quarkus.oidc-client.credentials.jwt.subject=XXX

    With the addition of those two properties I can do

    String accessToken = oidcClient.getTokens().onItem().transform(Tokens::getAccessToken).await().indefinitely();
    

    So the full set of properties are

    quarkus.oidc-client.discovery-enabled=false
    quarkus.oidc-client.auth-server-url=https://test.salesforce.com
    quarkus.oidc-client.token-path=/services/oauth2/token
    quarkus.oidc-client.client-id=XXXXXX
    quarkus.oidc-client.grant.type=jwt
    quarkus.oidc-client.credentials.jwt.assertion=true
    quarkus.oidc-client.credentials.jwt.subject=XXXXXXXX
    quarkus.oidc-client.credentials.jwt.audience=https://test.salesforce.com
    quarkus.oidc-client.credentials.jwt.lifespan=3600
    quarkus.oidc-client.credentials.jwt.key=-----BEGIN PRIVATE KEY-----\
    \nXXXX\
    \n-----END PRIVATE KEY-----