1

Our 2GP has an Aura component with a Canvas App that uses a Connected App to authenticate the Salesforce organization against an external service using the JWT Bearer OAuth flow.

Current flow follows Signed Request Authentication:

  1. User loads Opportunity Lightning Record Page with our Aura component
  2. Canvas lifecycle onRender Apex method is triggered which adds some custom parameters
  3. Salesforce takes the modified canvasRequest and generates a signed JWT using the Connected App's Consumer Key and its X509 certificate created from the Consumer Secret.
  4. Signed JWT is POSTed to canvas URL.
  5. Receiving server verifies JWT is correctly signed then processes other custom parameters.

Our Managed Package includes CspTrustedSite metadata so LWC could theoretically make REST calls directly to our service.

We want to create Lightning Web Components (LWC) to replace the Aura component.

Is there a way for an Apex method to generate a signed JWT using the Connected App? Been digging around the Canvas namespace but not seeing a way to do this.

1 Answer 1

2

You can generate a JWT signed token using the Connected app via Apex. This is described in the Apex Reference guide.

public class MyController{


 public MyController() {      
    Auth.JWT jwt = new Auth.JWT();
    jwt.setSub('<username>'); 
    jwt.setAud('https://login.salesforce.com'); 
    jwt.setIss('<consumerkeyfromconnectedapp>');
    
    //Additional claims to set scope
    Map<String, Object> claims = new Map<String, Object>();
    claims.put('scope', 'scope name');
        
    jwt.setAdditionalClaims(claims);

    //Create the object that signs the JWT bearer token
    Auth.JWS jws = new Auth.JWS(jwt, 'CertFromCertKeyManagement');
    
    //Get the resulting JWS in case debugging is required
    String token = jws.getCompactSerialization();
    
    //Set the token endpoint that the JWT bearer token is posted to
    String tokenEndpoint = 'https://login.salesforce.com/services/oauth2/token';
    
    //POST the JWT bearer token
    Auth.JWTBearerTokenExchange bearer = new Auth.JWTBearerTokenExchange(tokenEndpoint, jws);
    
    //Get the access token
    String accessToken = bearer.getAccessToken();

  }
}

The key is to make sure you also have a Certificate in the JKS format configured in the Certificate and Key Management. You can watch this full video to learn more about how to generate one.

I would like to caution not to output the JWT token to the front end JavaScript as that might cause a security vulnerability.

3
  • Thanks for the reply! So to confirm, this would generate a JWT that is compatible with one that would have been generated by the ConnectedApp (using the same Consumer Key and cert) but is not actually using those assets in the ConnectedApp, correct? Is there any way to programmatically extract the Consumer Key or certificate from an existing ConnectedApp? What I like about the existing packaging is that these are in the 1GP package so they don't get added to our source control. Jan 16 at 14:12
  • Its using the same asset for consumer key. For certificate you need to put into the certificate management Jan 16 at 21:42
  • 1
    As a side note, when we use a Canvas App inside an Aura Component, Salesforce sends the signed JWT to the client which then POSTS it to the canvas URL so it is normally exposed to end-users. Though with Apex making the outbound POST with the signed JWT, it will no longer need to go through the client. Jan 19 at 0:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .