| Available in: All Editions |
| User Permissions Needed | |
|---|---|
| To manage, create, edit, and delete OAuth applications: | “Manage Remote Access” |
JSON Web Token (JWT) is a JSON-based security token encoding that enables identity and security information to be shared across security domains.
The OAuth 2.0 JWT bearer token flow defines how a JWT can be used to request an OAuth access token from Salesforce when a client wishes to utilize a previous authorization. Authentication of the authorized application is provided by a digital signature applied to the JWT.
The OAuth 2.0 JWT bearer token flow is similar to a refresh token flow within OAuth. The JWT is POSTed to the OAuth token endpoint, which in turn processes the JWT, and issues an access_token based upon prior approval of the application. However, the client doesn’t need to have or store a refresh_token, nor is a client_secret required to be passed to the token endpoint.
JWT bearer flow supports two algorithms: HMAC SHA256 and RSA SHA256. HMAC SHA256 uses the consumer’s secret as the signing secret, while RSA SHA256 uses an uploaded certificate.
{"iss": "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQ
ukXnVjzRgSuQqGn75NL7yfkQcyy7",
"prn": "Pierre_Delacroix@SeattleApps.com",
"aud": "https://login.salesforce.com",
"exp": "1333685628"}eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoO UFLTF9yU0suQm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsIC Jwcm4iOiAiY2hhcmxpZW1vcnRpbW9yZUBnbWFpbC5jb20iLCAiYXVkIjogImh0dHB zOi8vbG9naW4uc2FsZXNmb3JjZS5jb20iLCAiZXhwIjogIjEzMzM2ODU2MjgifQ
encoded_JWT_Header + "." + encoded_JWT_Claims_Set
eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa 3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0suQm9TVlBHWkhRdWtYblZqelJnU3V RcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAiY2hhcmxpZW1vcnRpbW9yZUBnb WFpbC5jb20iLCAiYXVkIjogImh0dHBzOi8vbG9naW4uc2FsZXNmb3JjZS5jb20 iLCAiZXhwIjogIjEzMzM2ODU2MjgifQ
existing_string + "." + base64_encoded_signature
eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4 bm1BaUcxeFY0b0hoOUFLTF9yU0suQm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5Z mtRY3l5NyIsICJwcm4iOiAiY2hhcmxpZW1vcnRpbW9yZUBnbWFpbC5jb20iLCAiYXVkIj ogImh0dHBzOi8vbG9naW4uc2FsZXNmb3JjZS5jb20iLCAiZXhwIjogIjEzMzM2ODU2Mjg ifQ.iYCthqWCQucwi35yFs-nWNgpF5NA_a46fXDTNIY8ACko6BaEtQ9E6h4Hn1l_pcwcK I_GlmfUO2dJDg1A610t09TeoPagJsZDm_H83bsoZUoI8LpAA1s-2aj_Wbysqb1j4uDToz 480WtEbkwIv09sIeS_-QuWak2RXOl1Krnf72mpVGS4WWSULodgNzlKHHyjAMAHiBHIDNt 36y2L2Bh7M8TNWiKa_BNM6s1FNKDAwHEWQrNtAeReXgRy0MZgQY2rZtqT2FcDyjY3JVQb En_CSjH2WV7ZlUwsKHqGfI7hzeEvVdfOjH9NuaJozxvhPF489IgW6cntPuT2V647JWi7ng
The follow Java code is a simple example of constructing a JWT bearer token:
import org.apache.commons.codec.binary.Base64;
import java.io.*;
import java.security.*;
import java.text.MessageFormat;
public class JWTExample {
public static void main(String[] args) {
String header = "{\"alg\":\"RS256\"}";
String claimTemplate = "'{'\"iss\": \"{0}\", \"prn\": \"{1}\", \"aud\": \"{2}\", \"exp\": \"{3}\"'}'";
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] = "Pierre_Delacroix@SeattleApps.com";
claimArray[2] = "https://login.salesforce.com";
claimArray[3] = Long.toString( ( System.currentTimeMillis()/1000 ) + 300);
MessageFormat claims;
claims = new MessageFormat(claimTemplate);
String payload = claims.format(claimArray);
//Add the encoded claims object
token.append(Base64.encodeBase64URLSafeString(payload.getBytes("UTF-8")));
//Load the private key from a keystore
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(new FileInputStream("./path/to/keystore.jks"), "keystorepassword".toCharArray());
PrivateKey privateKey = (PrivateKey) keystore.getKey("certalias", "privatekeypassword".toCharArray());
//Sign the JWT Header + "." + JWT Claims Object
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(token.toString().getBytes("UTF-8"));
String signedPayload = Base64.encodeBase64URLSafeString(signature.sign());
//Separate with a period
token.append(".");
//Add the encoded signature
token.append(signedPayload);
System.out.println(token.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}JWT bearer tokens should be POSTed to the token endpoint at https://login.salesforce.com/services/oauth2/token or https://test.salesforce.com/services/oauth2/token.
POST /services/oauth2/token HTTP/1.1 Host: login.example.com Content-Type: application/x-www-form-urlencoded grant_type= urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=PHNhbWxwOl...[omitted for brevity]...ZT
After the request is verified, Salesforce sends a response to the client. Token responses for the OAuth 2.0 JWT bearer token flow follow the same format as authorization_code flows, although no refresh_token is ever issued. A JWT OAuth 2.0 bearer assertion request looks at all the previous approvals for the user that include a refresh_token. If matching approvals are found, the values of the approved scopes are combined and an access_token is issued. If no previous approvals included a refresh_token, no approved scopes are available, and the request fails as unauthorized.