IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Salesforce Integration - OAuth2.0 JWT Bearer Flow -> 正文阅读

[网络协议]Salesforce Integration - OAuth2.0 JWT Bearer Flow

应用场景

  1. Salesforce作为Service Provider (SP),外部系统需要访问Salesforce数据;
  2. 在授权过程中无需通过UI Login页面输入账密;
  3. 不希望外部系统储存账密等可直接用于UI Login的信息;

前置条件

  1. 使用证书对JWT请求进行签名;
  2. 需要事先获得SP的批准;

案例设计

目标

通过JWT授权方式获取access_token,然后使用access_token call Salesforce API访问数据。
在这里插入图片描述

前提假设

  1. 使用openSSL形式本地获取server.crt (public key)和server.key (private key),然后上传到Connected App与Certificate and Key Management提供安全保障;
  2. 使用JWTBearerTokenExchange class来获取access_token;
  3. 为方便Demo,假设使用同一个Org进行自己调自己API;

关键步骤

#1. 通过openSSL获取下面4个文件:
在这里插入图片描述
#2 将server.crt上传到Connected App:
在这里插入图片描述
#3. 将本地的server.crtserver.key通过terminal转化成JKS File,然后修改keystore的Alias name,最后在Certificate and Key Management通过Import from Keystore将JKS File保存到Certificates相关列表。
在这里插入图片描述
可通过下面命令转JKS File:

# 根据公钥和私钥生成server.p12
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12
# 根据server.p12生产jwt_apex.jks
keytool -importkeystore -srckeystore server.p12
        -srcstoretype PKCS12
        -destkeystore jwt_apex.jks
        -deststoretype JKS
# 修改keystore的默认alias name (默认是1)
keytool -keystore jwt-apex.jks -changealias -alias 1 -destalias jwt_apex
# 检查alias name是否修改正确
keytool -list -v -keystore jwt_apex.jks

为什么要修改alias name,以及alias name上传为Certificate时,有什么格式要求?

In order to successfully use “Import from Keystore” feature available at “Certificate and Key Management”, the ‘alias’ of the certificates within .JKS file must meet following criteria:
“The name must begin with a letter and use only alphanumeric characters and underscores. The name cannot end with an underscore or have two consecutive underscores.”

#4. 编写JWTApex.cls获取access_token:

public class JWTApex{
    /*
     * JWTApex.getAccessToken('https://login.salesforce.com', 
      						  'test@sample.com', 
      						  '3MVG9pRzaMkjMb6nq5_7vWB7bzj1AvzgpqUcBl0jDx6HcCZKgL5Ck.8WO2aexmvmyF2QrpGG7YHVYw2mEQqqF', 
     						  'jwt_apex');
	* Setup->Security->Remote site settings. endpoint = https://login.salesforce.com/services/oauth2/token
	*/
    public static String getAccessToken(String login_url, String username, String client_id, String certname) {      
        Auth.JWT jwt = new Auth.JWT();
        jwt.setSub(username); 
        jwt.setAud(login_url); 
        jwt.setIss(client_id);
        
        //Additional claims to set scope
        Map<String, Object> claims = new Map<String, Object>();
        claims.put('scope', 'scope name');
        
        jwt.setAdditionalClaims(claims);
        
        //Create the object that signs the JWT bearer token
        Auth.JWS jws = new Auth.JWS(jwt, certname);
        
        //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://login.salesforce.com/services/oauth2/token';
        
        //POST the JWT bearer token
        Auth.JWTBearerTokenExchange bearer = new Auth.JWTBearerTokenExchange(tokenEndpoint, jws);
        
        //Get the access token
        String accessToken = bearer.getAccessToken();
        return accessToken;
    }
}

此处需做2点说明:

  1. 通过System.debug无法获取明文access_token;
  2. 需要将tokenEndpoint添加到Remote site settings;

#5. 验证JWT获取的access_token是否可以自call SP的API:

public class JWTVerify {
    /*
     * JWTVerify.getInfoByServiceAPI('/appMenu/AppSwitcher/');
	*/
    public static void getInfoByServiceAPI(String service) {
        String token = JWTApex.getAccessToken('https://login.salesforce.com', 
      						  				  'test@sample.com', 
      						  				  '3MVG9pRzaMkjMb6nq5_7vWB7bzj1AvzgpqUcBl0jDx6HcCZKgL5Ck.8WO2aexmvmyF2QrpGG7YHVYw2mEQqqF', 
     						  				  'jwt_apex');
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        // without Auth: [{"message":"Session expired or invalid","errorCode":"INVALID_SESSION_ID"}]
        request.setHeader('Authorization', 'Bearer ' + token);
        request.setEndpoint('https://pkg-instance1-dev-ed.my.salesforce.com/services/data/v55.0' + service);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        
        System.debug(response.getBody());
    }
}

心得体会

  1. 如果我们使用两个Salesforce Org来验证Salesforce JWT授权方式会更加make sense;
  2. 关键步骤#4中使用的是官方的sample code,这种方式无法明文打印access_token,想通过临时access_token在postman中做API调试行不通;
  3. 这里强哥提供了另一种思路sample code,但也无法明文打印access_token;
  4. 如果是Salesforce Org之间想通过JWT授权,不妨使用Named Credentials方式;

小工具

JWT.IO allows you to decode, verify and generate JWT
https://jwt.io/

参考文档

  1. OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration
  2. JWTBearerTokenExchange Class
  3. Oauth Authorization flows in Salesforce
  4. How to convert crt and key to jks file
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-06-20 23:08:51  更:2022-06-20 23:08:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:31:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码