Loading
识别您的用户并管理访问
目录
选择筛选器

          没有结果
          没有结果
          以下是一些搜索提示

          检查关键字的拼写。
          使用更普遍的搜索词。
          选择更少的筛选器,并扩大搜索范围。

          搜索所有 Salesforce 帮助
          适用于服务器到服务器集成的 OAuth 2.0 JWT 不记名流

          适用于服务器到服务器集成的 OAuth 2.0 JWT 不记名流

          有时,您希望授权服务器访问数据,而不必每次服务器交换信息时都交互登录。对于一些情况,您可以使用 OAuth 2.0 JSON Web 令牌 (JWT) 不记名流。此流会使用证书签名 JWT 请求,且无需显式用户集成。但是,此流确实需要客户端应用程序的事先批准。

          所需的 Edition

          适用于 Salesforce Classic 和 Lightning Experience
          适用于:所有版本

          通过 OAuth 2.0 JWT 不记名令牌流,客户端会将 JWT 发布到 Salesforce OAuth 令牌端点。Salesforce 处理包含数字签名的 JWT,并根据应用程序的事先批准发布访问令牌。

          此示例显示了流中采取的步骤。

          1. 报表服务开始其夜间批处理报表。
          2. 连接的应用程序向 Salesforce 标记端点发送 JWT。JWT 启用在安全域之间共享的身份和安全信息。
          3. Salesforce 使用先前配置的证书和其他参数,基于签名验证 JWT。
          4. 假设 JWT 有效,并且连接的应用程序已事先获得批准,Salesforce 会发出访问令牌。通过以下其中一种方式进行事先批准:
            • 如果连接的应用程序策略设置为管理员批准的用户已预授权,您可以使用简档和权限集。
            • 如果连接的应用程序策略设置为所有用户可以自我授权,您可以使用最终用户批准并发布刷新令牌。但是,客户端不需要有当前或存储的刷新令牌。客户端也不需要将客户端密钥发送到令牌端点。
            备注
            备注 对于这两个选项,Salesforce 仅在原始访问令牌包含至少一个标准范围(而非refresh_token范围)时发布新访问令牌。
          5. 连接的应用程序使用访问令牌访问 Salesforce 服务器上受保护的数据。
          6. 报表服务将授权数据拉入其夜间报表中。
          备注
          备注 此流始终不会发行刷新令牌。

          让我们回顾一下该授权流的每一步。

          创建 JWT

          Salesforce 要求使用 RSA SHA256 对 JWT 进行签名,RSA sha 256 使用上传的证书作为签名密码。在使用此授权流之前,请确保您已完成这些步骤。

          • 将 X509 证书上传到 Java 密钥存储 (JKS)。证书大小不能超过 4 KB。如果超过,请尝试使用 DER 编码的文件来减小大小。
          • 为连接的应用程序注册 X509 证书。该证书对应于其应用的私钥。保存连接的应用程序时,将生成client_idclient_secret并分配给应用程序。
          • 构建可生成 JWT 的应用程序,该应用程序使用 X509 证书的私钥进行签名。关联的已连接应用程序使用证书来验证签名。JWT 必须符合 https://tools.ietf.org/html/rfc7519 指定的一般格式规则。
            备注
            备注 Salesforce 在您的 JWT 不记名令牌中不要求 JWT ID (JTI) 声明。但是,如果您通过了 JWT 不记名令牌中的 JTI 声明,Salesforce 会验证之前没有发送过 JTI 声明。这种验证可以防止 JWT 重放攻击。

          要创建有效的 JWT,请执行以下步骤。

          1. 以此格式构建 JWT 标题:{"alg":"RS256"}.
          2. 按照 http://tools.ietf.org/html/rfc4648#page-7 中的定义,Base64url 解码 JWT 标题。结果类似于 eyJhbGciOiJSUzI1NiJ9
          3. 使用这些参数为 JWT 构建 JSON 请求集。
            参数描述
            iss 颁发者必须包含您为其注册证书的连接的应用程序的 OAuth client_id
            aud

            受众会将授权服务器识别为目标受众。授权服务器必须验证它是令牌的目标受众。

            使用授权服务器的 URL 作为受众值:https://login.salesforce.comhttps://test.salesforce.comhttps://site.force.com/customers(如果为 Experience Cloud 站点实施)。

            sub

            如果您正在为 Experience Cloud 站点实施该流,主题必须包含用户的用户名。

            为了向后兼容,您可以使用主体 (prn) 而不是主题 (sub)。如果两者都指定,则使用 prn

            exp 令牌过期的日期和时间,以从协调世界时 1970-01-01T0:0:0Z 开始测量的秒数表示。Salesforce 允许 3 分钟的时钟偏差缓冲时间。例如,如果过期时间设置为 1,735,743,600 秒或世界协调时 2025 年 1 月 1 日 15:00:00C,则令牌在世界协调时此日期的 15:03:00 之前仍然有效。
            以下是 JWT 的 JSON 请求集示例。
            {"iss": "3MVG99OxTyEMCQ3gNp2PjkqeZKxnmAiG1xV4oHh9AKL_rSK.BoSVPGZHQ
            ukXnVjzRgSuQqGn75NL7yfkQcyy7", 
            "sub": "my@email.com", 
            "aud": "https://login.salesforce.com", 
            "exp": "1333685628"}
          4. Base64url 编码 JWT“请求设置”,无任何换行符。例如:
            eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
            Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
            Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
            Njg1NjI4In0=
          5. 在此格式,创建字符串用于编码 JWT 标题和编码 JWT “请求设置”:
            encoded_JWT_Header + "." + encoded_JWT_Claims_Set
            在此示例中,编码 JWT 标题会突出显示。
            eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
            Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
            Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
            Njg1NjI4In0=
          6. 从 JKS 下载 X509 证书。
          7. 使用 RSA SHA256 对结果字符串进行签名。
          8. 以此格式创建此步骤中的字符串。
            existing_string + "." + base64_encoded_signature
            在此示例中,base64 编码签名会突出显示。
            eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiM01WRzk5T3hUeUVNQ1EzZ05wMlBqa3FlWkt4bm1BaUcxeFY0b0hoOUFLTF9yU0su
            Qm9TVlBHWkhRdWtYblZqelJnU3VRcUduNzVOTDd5ZmtRY3l5NyIsICJwcm4iOiAibXlAZW1haWwu
            Y29tIiwgImF1ZCI6ICJodHRwczovL2xvZ2luLnNhbGVzZm9yY2UuY29tIiwgImV4cCI6ICIxMzMz
            Njg1NjI4In0=.iYCthqWCQucwi35yFs-nWNgpF5NA_a46fXDTNIY8ACko6BaEtQ9E6h4Hn1l_pcwcK​
            I_GlmfUO2dJDg1A610t09TeoPagJsZDm_H83bsoZUoI8LpAA1s-2aj_Wbysqb1j4uDToz​
            480WtEbkwIv09sIeS_-QuWak2RXOl1Krnf72mpVGS4WWSULodgNzlKHHyjAMAHiBHIDNt​
            36y2L2Bh7M8TNWiKa_BNM6s1FNKDAwHEWQrNtAeReXgRy0MZgQY2rZtqT2FcDyjY3JVQb​
            En_CSjH2WV7ZlUwsKHqGfI7hzeEvVdfOjH9NuaJozxvhPF489IgW6cntPuT2V647JWi7ng

          对于构建 JWT 不记名令牌,此 Java 代码是一个简单示例。

          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}\", \"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[5];
                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);
          
                //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();
              }
            }
          }

          请求访问令牌

          要请求访问令牌,连接的应用程序会向 Salesforce 实例的标记端点发布标记请求。它在帖子中包括 JWT。

          此示例显示示例标记请求。

          POST /services/oauth2/token HTTP/1.1
          Host: login.example.com
          Content-Type: application/x-www-form-urlencoded
          
          grant_type= urn:ietf:params:oauth:grant-type:jwt-bearer&
          assertion=eyJpc3MiOiAiM01WRz...[omitted for brevity]...ZT
          重要
          重要 在开发 OAuth 集成时,请始终在 POST 请求的正文或请求标题中传递敏感信息。不要在 URL 查询字符串中使用 GET 参数来传递敏感信息。敏感信息包括但不限于用户名、密码、OAuth 令牌、客户端密码和任何个人身份信息。有关安全最佳实践的更多信息,请查看安全编码指南中的存储敏感数据

          在帖子中包括这些参数。

          参数 描述
          grant_type 将这些值用于资助类型:urn:ietf:params:oauth:grant-type:jwt-bearer.
          assertion 声明是整个 JWT 值。
          format

          (可选)用于指定预期返回格式。此参数会覆盖请求的标题。支持这些格式。

          • urlencoded
          • json(默认)
          • xml

          范围参数

          您无法在 JWT 不记名令牌流中指定范围。范围根据连接的应用程序的允许用户策略或贵组织的 API 访问控制设置而颁发,如本表所示。

          设置 结果
          允许的用户策略:所有用户可以自我授权 通过成功授权,使用访问令牌返回的范围将从先前批准的范围派生。
          允许的用户策略:管理员批准的用户是预先授权的 分配给连接的应用程序的标准和自定义范围将随访问令牌一起返回。
          API 访问权限控制将组织中连接的应用程序加入允许列表

          分配给连接的应用程序的标准和自定义范围将随访问令牌一起返回。如果您将组织中连接的应用程序加入允许列表,但未收到预期范围,请采取以下步骤。

          • 从“设置”中,在快速查找框中输入 OAuth,然后选择连接的应用程序 OAuth 使用情况
          • 对于已加入允许列表的连接的应用程序,单击阻止
          • 对于已加入允许列表的连接的应用程序,单击解除阻止

          Salesforce 授予访问令牌

          OAuth 2.0 JWT 不记名和 SAML 声明不记名流请求查看包含刷新标记的用户的所有先前批准。如果 Salesforce 查找匹配批准,将合并批准范围的值。然后,Salesforce 发行访问令牌。如果 Salesforce 未找到包含刷新令牌或任何可用批准范围的先前批准,请求会因为未授权而失败。

          验证成功后,Salesforce 实例会向连接的应用程序发送响应。虽然从未发行刷新令牌,但 OAuth 2.0 JWT 不记名令牌流的令牌响应使用与授权码流相同的格式。

          此示例显示来自 Salesforce 的响应。

          {"access_token":"00Dxx0000001gPL!AR8AQJXg5oj8jXSgxJfA0lBog.
          39AsX.LVpxezPwuX5VAIrrbbHMuol7GQxnMeYMN7cj8EoWr78nt1u44zU31
          IbYNNJguseu",
          "scope":"web openid api id","instance_url":"
          https://yourInstance.salesforce.com","id":"
          https://yourInstance.salesforce.com
          /id/00Dxx0000001gPLEAY/005xx000001SwiUAAS","token_type":"Bearer"}

          这些参数在响应的正文中。

          参数描述
          access_token 连接的应用程序用来代表客户端应用程序请求访问受保护资源的 OAuth 标记。访问标记可以附带范围形式的附加权限。
          token_type Bearer 令牌类型,用于包含访问令牌的所有响应。
          scope 范围根据连接的应用程序的允许用户策略或贵组织的 API 访问控制设置而颁发。请查看范围参数
          instance_url 指示用户的组织实例的 URL。例如:https://yourInstance.salesforce.com/.
          id 可用于标识用户以及查询有关用户的更多信息的身份 URL。请参阅身份 URL
          sfdc_site_url 如果用户是 Experience Cloud 站点的成员,则提供站点 URL。
          sfdc_site_id 如果用户是 Experience Cloud 站点的成员,则提供用户的站点 ID。对于 Experience Cloud 站点,此流在令牌端点中包含"sfdc_site_id"值。在连接 REST API 请求中可能需要该站点 ID。

          访问受保护的数据

          连接的应用程序收到access_token后,可以在授权标题请求中将其作为不记名令牌传递。此示例显示 REST API 调用至 Experience Cloud 站点:

          
                    https://site.force.com/customers/services/data/v32.0/ -H 
          "Authorization: Bearer 00D50000000IehZ\!AQcAQH0dMHZfz972Szmpkb58urFRkgeBGsxL_QJWwYMfAbUeeG7c1E6 LYUfiDUkWe6H34r1AAwOR8B8fLEz6n04NPGRrq0FM"
                  

          另请参阅:

           
          正在加载
          Salesforce Help | Article