Salesforce 命名凭证:安全 API 集成的综合指南

背景与应用场景

作为一名 Salesforce 集成工程师 (Salesforce Integration Engineer),我的日常工作核心就是将 Salesforce 与外部系统无缝、安全地连接起来。在过去,处理对外部服务的 API 调用 (Callout) 是一项繁琐且充满安全隐患的任务。我们经常需要在 Apex 代码或自定义设置中硬编码认证信息,例如用户名、密码或 API 密钥。这种做法带来了几个致命的问题:

1. 安全风险:凭证以明文或半明文形式存储在代码或元数据中,一旦代码泄露,整个外部系统的安全都将受到威胁。

2. 维护噩梦:当外部系统的凭证或端点 (Endpoint) URL 发生变更时(例如,从沙箱切换到生产环境,或密码定期轮换),我们需要深入代码进行修改、测试并重新部署。这个过程耗时耗力,且极易出错。

3. 认证复杂性:处理像 OAuth 2.0 这样的复杂认证协议,需要编写大量样板代码来管理令牌 (Token) 的获取、刷新和存储,这增加了开发的复杂度和出错的概率。

为了解决这些痛点,Salesforce 推出了 Named Credentials (命名凭证)。它是一种将 API 端点 URL 与其所需的认证参数打包在一起的配置方式,从根本上改变了我们在 Salesforce 中进行外部服务调用的模式。通过 Named Credentials,我们将认证的细节从代码中完全剥离,交由 Salesforce 平台来管理。

核心应用场景:

  • 连接 ERP 系统:从 Salesforce 调用 SAP 或 Oracle ERP 的 API,同步订单、客户或库存数据。
  • 集成支付网关:在 Salesforce Commerce Cloud 或 CPQ 中安全地调用 Stripe、PayPal 等支付接口。
  • 调用公共 API:获取外部服务数据,如通过天气 API 获取地理位置信息,或通过快递查询 API 跟踪物流状态。
  • 微服务集成:在复杂的系统架构中,Salesforce 需要与公司内部的多个微服务进行交互。

对于集成工程师而言,Named Credentials 不仅仅是一个功能,更是一种构建可维护、可扩展和安全集成的最佳实践。


原理说明

Named Credentials 的核心思想是 “解耦”——将“去哪里” (Endpoint URL)“如何验证身份” (Authentication) 这两个关注点与业务逻辑代码分离。它通过一个统一的配置入口,让管理员能够集中管理所有出站 API 调用的端点和凭证。

一个 Named Credential 主要由以下几个关键部分组成:

1. URL

这是外部服务的根 URL。在进行 API 调用时,我们不再需要在代码中指定完整的 URL,而是使用一种特殊的语法:callout:My_Named_Credential_Name/some_path。Salesforce 会在运行时将 callout:My_Named_Credential_Name 替换为配置好的 URL,并附加后面的路径。

2. Identity Type (身份类型)

这决定了 Salesforce 在连接到外部系统时使用谁的身份凭证。

  • Named Principal (指定负责人): 整个 Salesforce 组织共享一套凭证来访问外部系统。这是最常见的场景,适用于系统到系统的集成,例如,Salesforce 使用一个统一的 API 账户去访问公司内部的订单管理系统。
  • Per User (每位用户): 每个 Salesforce 用户使用自己的凭证来访问外部系统。这种模式通常与 OAuth 2.0 结合使用。例如,当一个销售人员想要从 Salesforce 访问他自己的 Google Drive 文件时,系统会使用该销售人员自己的 Google 账户进行认证。Salesforce 会为每个用户安全地管理其个人的 OAuth Token。

3. Authentication Protocol (认证协议)

这是 Named Credentials 最强大的部分,Salesforce 平台内置了对多种主流认证协议的支持,我们只需进行配置,无需编写复杂的认证代码。

  • No Authentication: 用于访问无需认证的公开 API。
  • Password Authentication: 对应 HTTP Basic Authentication。你只需提供用户名和密码,Salesforce 会自动生成并添加 Authorization: Basic [base64-encoded-string] 请求头。
  • OAuth 2.0: 这是最常用且最安全的协议之一。你需要配置一个 Auth. Provider (验证提供商),并提供客户端 ID、客户端密钥、作用域 (Scope) 等信息。Salesforce 会自动处理整个 OAuth 2.0 授权流程,包括获取和刷新 Access Token 和 Refresh Token。这极大地简化了开发工作。
  • JWT (JSON Web Token): 允许 Salesforce 使用数字签名过的 JWT 作为凭证来向外部系统进行认证。
  • JWT Token Exchange: 一种更高级的 OAuth 流程,允许用一个 JWT 换取一个访问令牌。
  • AWS Signature Version 4: 专为集成 Amazon Web Services (AWS) 而设计,Salesforce 会自动处理复杂的 AWS 请求签名过程。

值得注意的是,Salesforce 近期引入了 External Credentials (外部凭证) 的概念,它将认证协议的配置 (如 OAuth 2.0 的客户端密钥) 与 Principal (负责人,即具体的用户凭证) 分离,而 Named Credential 则专注于定义端点 URL 并引用一个 External Credential。这种新的模型提供了更大的灵活性和重用性,是当前推荐的最佳实践。


示例代码

让我们来看一个经典的 Apex Callout 场景。假设我们需要调用一个外部的订单查询服务,该服务使用密码认证。我们已经创建了一个名为 My_Legacy_ERP 的 Named Credential。

Apex Callout 示例

下面的 Apex 代码展示了如何使用这个 Named Credential 来发起一个 HTTP GET 请求。请注意代码的简洁性——完全没有出现任何 URL 或凭证的痕迹。

// 详细注释
// @author Salesforce Developer Documentation
// @description 此示例演示如何使用 Named Credential 执行 Apex callout。
// Salesforce 平台会自动处理端点解析和身份验证。

public class ApexCalloutWithNamedCredential {
    public static HttpResponse getOrders() {
        // 1. 创建一个新的 HttpRequest 对象。
        HttpRequest req = new HttpRequest();

        // 2. 设置请求的端点(Endpoint)。
        //    这里的语法是关键:'callout:My_Legacy_ERP/api/orders'
        //    'callout:' 是一个特殊协议,告诉 Salesforce 使用 Named Credential。
        //    'My_Legacy_ERP' 是我们在 Salesforce 设置中定义的 Named Credential 的名称。
        //    '/api/orders' 是相对于 Named Credential 中定义的根 URL 的具体路径。
        //    Salesforce 在运行时会将 'callout:My_Legacy_ERP' 替换为
        //    例如 'https://api.my-erp.com',并自动附加认证头。
        req.setEndpoint('callout:My_Legacy_ERP/api/orders');

        // 3. 设置 HTTP 请求方法为 'GET'。
        req.setMethod('GET');

        // 4. 创建一个 Http 对象来发送请求。
        Http http = new Http();

        // 5. 发送请求并获取 HttpResponse 对象。
        //    在这个过程中,Salesforce 会在后台:
        //    - 查找名为 'My_Legacy_ERP' 的 Named Credential。
        //    - 获取其配置的 URL 和认证信息(例如,用户名和密码)。
        //    - 根据认证协议(Password Authentication),生成 'Authorization' 请求头。
        //    - 将请求发送到最终的 URL (https://api.my-erp.com/api/orders)。
        //    如果认证失败或网络出现问题,这里可能会抛出 CalloutException。
        HttpResponse res = http.send(req);

        // 6. (可选)在调试日志中打印响应的状态码和响应体,以便调试。
        System.debug('Status Code: ' + res.getStatusCode());
        System.debug('Response Body: ' + res.getBody());

        // 7. 返回完整的 HttpResponse 对象,供调用者处理。
        return res;
    }
}

正如你所见,代码变得异常干净和安全。集成工程师只需要关注业务逻辑(请求什么数据、如何处理返回的数据),而无需关心认证的实现细节。


注意事项

在使用 Named Credentials 时,有一些关键点需要特别注意,以确保集成的顺利和安全。

1. 权限 (Permissions)

  • 创建和管理:创建和修改 Named Credentials 需要用户拥有 “Customize Application” (自定义应用程序) 权限。通常只有 Salesforce 管理员或具有相应权限的开发人员才能进行此操作。
  • 访问权限:对于 Per User 身份类型的 Named Credential,需要通过权限集 (Permission Set) 或简档 (Profile) 来授权用户访问特定的 External Credential Principal。这确保了只有授权用户才能启动对外部系统的 OAuth 流程。

2. API 限制 (API Limits)

Named Credentials 是一种简化调用的方式,但它并不会绕过 Salesforce 的 Governor Limits。每次通过 Named Credential 的调用仍然计入组织的 API Callout 限制(例如,每个事务中最多 100 次调用)。你需要像处理普通 Callout 一样,进行批量化处理和错误监控。

3. 错误处理 (Error Handling)

当认证失败(例如,密码错误、OAuth token 过期且无法刷新)或网络连接中断时,http.send(req) 方法会抛出 System.CalloutException。你的 Apex 代码必须包含 try-catch 块来捕获这个异常,并执行优雅的降级逻辑,例如记录错误日志、向用户显示友好的错误信息等。

此外,即使 Callout 成功(没有抛出异常),HTTP 响应的状态码也可能是 4xx (客户端错误) 或 5xx (服务器错误)。必须检查 res.getStatusCode() 来判断业务逻辑是否成功执行。

4. 命名空间和包 (Namespaces and Packages)

在托管包 (Managed Package) 中,你可以包含 Named Credentials。但是,端点 URL 和认证信息通常需要由订阅组织的管理员在安装后进行配置。在代码中引用 Named Credential 时,如果它在你的包的命名空间内,你需要使用 callout:YourNamespace__My_Named_Credential/path 这样的格式。

5. 安全性 (Security)

始终选择可用的最强认证协议。优先使用 OAuth 2.0 或 JWT,而不是 Password Authentication (Basic Auth),因为后者在传输过程中更容易被截获(除非全程使用 HTTPS)。Named Credentials 将凭证加密存储在 Salesforce 数据库中,不会在调试日志中显示,这远比硬编码安全。


总结与最佳实践

Named Credentials 是 Salesforce 平台集成工具箱中不可或缺的基石。对于任何需要与外部系统通信的场景,它都应该是首选方案。它通过抽象和封装认证细节,带来了无与伦比的安全性、可维护性和开发效率。

作为一名集成工程师,我总结的最佳实践如下:

  1. 永远不要硬编码:任何时候都不要在代码、自定义标签或自定义元数据中存储端点 URL 或凭证。始终使用 Named Credentials
  2. 拥抱新模型:尽可能使用最新的 External Credential + Named Credential 组合。这种模式提供了更高的灵活性,例如可以为同一个外部服务(同一个 External Credential)定义多个不同的端点(不同的 Named Credential),或者为不同的认证场景定义不同的 Principal。
  3. 为环境创建不同的凭证:为你的开发、测试 (UAT) 和生产环境分别创建 Named Credentials。这样,在不同环境之间迁移代码时,无需修改任何代码,只需确保目标环境中存在同名的 Named Credential 即可。
  4. 明确身份类型:仔细考虑应该使用 Named Principal 还是 Per User。选择错误的类型可能会导致不符合预期的行为或安全问题。
  5. 精细化权限控制:使用权限集来控制对 Per-User 类型凭证的访问,确保遵循最小权限原则。

总而言之,熟练掌握和运用 Named Credentials 是衡量一个 Salesforce 专业人员集成能力的重要标准。它不仅能让你的集成方案更健壮、更安全,还能让你从繁琐的认证管理中解放出来,更专注于实现核心的业务价值。

评论

此博客中的热门博文

Salesforce Einstein AI 编程实践:开发者视角下的智能预测

Salesforce 登录取证:深入解析用户访问监控与安全

Salesforce Experience Cloud 技术深度解析:构建社区站点 (Community Sites)