在之前的文章中介绍了什么是 JWT Token, 以及如何创建 JWT Token, 并通过 JWT Token 获取 Salesforce 访问令牌,今天主要介绍如何在 Salesforce Apex 类中使用同样的功能。目前 Salesforce 只支持 Java Keystore(JKS) 格式,用于将私钥/公钥对 (含证书) 导入 Salesforce org 中。
将私钥/公钥对转换为 Salesforce Keystore JKS 文件
- 在 server.key 文件的同一文件夹 (通过之前的文章创建的。克隆 server.key 文件并保存为 server.pem.
- 执行如下命令:
1
2
3
4
5
6
7
8
// 第一步
openssl pkcs12 -export -in server.crt -inkey server.pem -out keystore.p12
//第二步
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore jwt_flow.jks -deststoretype JKS
//第三步
keytool -keystore jwt_flow.jks -changealias -alias 1 -destalias jwt_flow
将 JKS 文件导入 Salesforce 里
setup
-> 搜索关键词 Certificate and Key Management- 点击
Import From Keystore
. - 上传
jwt_flow.jks
文件,并提供你创建jwt_flow.jks
文件的密码。
在 Apex 里使用 JWT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class JWTBearerFlow {
public static String getAccessToken() {
Auth.JWT jwt = new Auth.JWT();
jwt.setSub('salesforce@example.com');
jwt.setAud('https://<your instance>.salesforce.com');
jwt.setIss('connected app client id');
//Create the object that signs the JWT bearer token
Auth.JWS jws = new Auth.JWS(jwt, 'Certificate keystore name');
//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://<your instance>.salesforce.com/services/oauth2/token';
//POST the JWT bearer token
Auth.JWTBearerTokenExchange bearer = new Auth.JWTBearerTokenExchange(
tokenEndpoint,
jws
);
//return access token
return bearer.getAccessToken();
}
}
不过我们发现上面代码的所有实现细节有被呈现出来,这样的类是不安全的。这在 Salesforce 中不是最佳实践。我建议使用如下 Named Credentials
来实现:
如图所示:
代码更新如下:
1
2
3
4
5
6
7
8
9
String service_limits = '/services/data/v56.0/sobjects/Account/listviews/';
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:JWT_Flow' + service_limits);
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());