-1

I tried to connect Salesforce from Spring boot webclient. I have the JWT token with the below code

String header = "{\"alg\":\"RS256\"}";
String claimTemplate = "'{'\"iss\": \"{0}\", \"sub\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\", \"jti\": \"{4\"'}'";

try {
  StringBuffer token = new StringBuffer();

  //Encode the JWT Header and add it to our string to sign
  token.append(Base64.encodeBase64URLSafeString(header.getBytes("UTF-8")));

  //Separate with a period
  token.append(".");

  //Create the JWT Claims Object
  String[] claimArray = new String[4];
  claimArray[0] = "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQukXnVjzRgSuQqGn75NL7yfkQcyy7";
  claimArray[1] = "my@email.com";
  claimArray[2] = "https://login.salesforce.com";
  claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
  claimArray[4]=<JTI>
  MessageFormat claims;
  claims = new MessageFormat(claimTemplate);
  String payload = claims.format(claimArray);
  token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));

  KeyStore keystore = KeyStore.getInstance("JKS");
  keystore.load(new FileInputStream("./path/to/keystore.jks"), "keystorepassword".toCharArray());
  PrivateKey privateKey = (PrivateKey) keystore.getKey("certalias", "privatekeypassword".toCharArray());

  Signature signature = Signature.getInstance("SHA256withRSA");
  signature.initSign(privateKey);
  signature.update(token.toString().getBytes("UTF-8"));
  String signedPayload = Base64.encodeBase64URLSafeString(signature.sign());
  token.append(".");
  token.append(signedPayload);


    System.out.println(token.toString());
} catch (Exception e) {
        e.printStackTrace();
    }

As per Salesforce site mentioned below. I have the private key .der file in my classpath.

I have got the AuthToken with the below code.

    HttpClient client = HttpClient.create();
    ReactorClientHttpConnector conn = new ReactorClientHttpConnector(client);
WebClient web = WebClient.builder()
        .baseUrl("https://dev.salesforce.com")
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
        .clientConnector(conn).build();

Mono<Token> token = web.post()
            .uri("/services/oauth2/token")
            .body(BodyInserters.fromFormData("grant_type", "jwt-bearer")
            .with("assertion", getAuth()).exchange().flatMap(res->res.bodyToMono(Token.class));
return token;

But I am getting reactor.core.Exceptions$Reactiveexception io.netty.channel.AbstractChannel$AnnotatedConnectionException: connection timedout exception with no further information exception.

Kindly let me know what am I missing in the post Auth Token creation method.

Neela
  • 107
  • 2
  • 10

1 Answers1

0

If you view your user in SF setup, on the bottom is login history. Does it show any errors? Does it even login ok and "just" die on actual API call?

In JWT flow you aren't supposed to send to SF the whole token as Authorization header. You'd start with token, SF would send you a message back, from that message use "access_token" in subsequent calls... https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&language=en_us has even Java sample.

eyescream
  • 18,088
  • 2
  • 34
  • 46
  • Thank you so much for your reply. I have checked the url and am getting the above metioned error. Please add your suggestion. Thanks in advance – Neela Nov 22 '20 at 14:45
  • Timeout suggests something is blocking your requests. Do you have firewall that needs configuring? Proxy? Do any other callouts from this Java app work OK? You checked the SF user's login history, is there even a login attempt recorded or nothing? Can you try with a simpler (less secure) flow like https://help.salesforce.com/articleView?id=remoteaccess_oauth_username_password_flow.htm&r=https:%2F%2Fwww.google.com%2F&type=5. You could run it even in Postman, curl, SoapUI, it's not as tricky as JWT. Just to rule out connectivity issues. Screenshots in https://stackoverflow.com/a/53568558/313628 – eyescream Nov 22 '20 at 18:28
  • Yes you are right because of the firewall issue it didn't work. Once it got fixed it started to work properly. Thank you so much. – Neela Dec 07 '20 at 15:11