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.