2

I failed to request an access token.

Following doc to authentification using JWT, I already have my connected app, my JWT Key so I just need to make a POST requestion to : https://test.salesforce.com/services/oauth2/token

Params are on the body :

grant_type : urn:ietf:params:oauth:grant-type:jwt-bearer
assertion : the content of my jwt.key (private key)

I'm having error 400 :

{
"error": "invalid_grant",
"error_description": "invalid assertion"
}

Also added : Content-Type : application/x-www-form-urlencoded

What should I correct/add ?

  • assertion : the content of my jwt.key (private key) ? shouldn't be the private key of my certificat ?
  • add authorization => basic auth and ask my administrator to send me username/password of my connected app ?
identigral
  • 7,543
  • 29
  • 32
  • 42
BestAboutMe
  • 349
  • 1
  • 4
  • 12

3 Answers3

4

It seems you haven't followed the JWT bearer flow documentation correctly.

You're not sending the private key directly (and if you have, you should consider it compromised and generate a new keypair and certificate), but rather using it to "sign" a copy of your payload (which, as I understand is hashing with sha256 followed by encrypting with the private key).

Having the certificate in Salesforce is then what allows you (well, Salesforce) to verify the signature (decrypt the signature with the public key in the cert, hash the original data, compare the two hashes, and make a determination whether or not the request was modified in-flight).

The structure of the JWT assertion looks like this

Base64URL({header}).Base64URL({claims}).Base64URL(RSA(SHA256(Base64URL({header}).Base64URL({claims}))))

or grouped a bit differently for readability

encodedHeader = Base64URL({header})
encodedClaims = Base64URL({claims})
token = encodedHeader.encodedClaims

assertion = token.Base64URL(RSA(SHA256(token)))

The private key is used in generating the signature (i.e. the second part of the "assertion"). If your assertion doesn't start with eyJhbGciOiJSUzI1NiJ9 (the Base64 encoded version of {"alg":"RS256"}) then it is wrong.

You also need to ensure the following:

  • The scopes granted by your connected app include "access and manager your data (api)", "perform requests on your behalf at any time (refresh_token, offline_access)"
  • The connected app is installed in your target org
  • The connected app is configured to "Use Digital Signatures", and you've uploaded the certificate (.crt file)
  • If you're installing the connected app in another org (i.e. the connected app is in your production org and you want to use it to authenticate with a new sandbox), you'll need to go through another OAuth flow (like the Web-Server or User-Agent flows) to avoid the user hasn't approved this consumer error. This question goes into more detail on that.
Derek F
  • 61,401
  • 15
  • 50
  • 97
  • @identigral No need to be rude. I rejected your edit because it made changes to what I felt were some key phrases without any explanation. I have since done a bit of additional research and gotten some clarity on the topic. I'll review my wording again at my earliest convenience. – Derek F Jun 02 '20 at 20:01
  • Fair enough, apologies for a rash comment. We thought a quick edit was better than commenting, will provide an explanation next time. – identigral Jun 02 '20 at 20:37
  • Thank you @DerekF for so detailed answer, indeed I did not read carfully doc. Just a question, to create a JWT using RS256 I'll need only Private key ? no need to add cert into my cacerts ? – BestAboutMe Jun 03 '20 at 20:59
  • @BestAboutMe I don't know enough about your environment to give a definitive answer on that, but I believe that's technically correct. If you need more help, the best advice I can give right now is to read the JWT bearer documentation again. Specifically, the given example in Java. If you're not using Java, you'll just need to find suitable replacements (e.g. Signature.getInstance("SHA256withRSA"); and the like in Java would be handled by something like openssl_sign() with OPENSSL_ALGO_SHA256 passed as the algorithm in PHP) – Derek F Jun 03 '20 at 21:51
0

I got the following...

ERROR running auth:jwt:grant:  We encountered a JSON web token error, which is likely not an issue with Salesforce CLI. Here’s the error: Error authenticating with JWT config due to: invalid assertion

... which was because I didn't upload my server.crt to the Connected App (or rather, Save didn't take it ;) ).

-1

I got this exception, too. In Salesforce the certificate (public key) was missing. Maybe during your tests the certificate was removed.

In connected app form:

  • Assure that the field Digital Certificate is filled with a valid certificate (not expired)

  • Please assure that these flags are set:

    • Require Secret for Web Server Flow
  • We set these flag as well inspite of we don't get an refresh token

    • Require Secret for Refresh Token Flow
Maik
  • 101
  • 1