datai/datai-scenes/datai-scene-salesforce/docs/reference-code/datai-salesforce-auth模块详细文档.md

26 KiB
Raw Permalink Blame History

datai-salesforce-auth 模块详细文档

模块概述

基本信息

  • 模块名称: datai-salesforce-auth
  • 模块类型: 认证和会话管理模块
  • 版本: 1.0.0
  • Java 版本: 22
  • 编码: UTF-8

功能描述

datai-salesforce-auth 模块负责 Salesforce 认证和会话管理,提供多种登录方式支持、会话信息缓存、连接工厂等核心功能。该模块是整个 Salesforce 集成体系的基础为其他模块Partner、Apex、Metadata、Tooling提供统一的认证和会话管理能力。

核心特性

  1. 多种登录方式支持OAuth2、Salesforce CLI、Legacy Credential、Session ID
  2. 会话管理:自动 Session 有效性检查、过期自动刷新
  3. 连接工厂:统一的连接创建和管理接口
  4. 登录历史:完整的登录历史记录和查询
  5. 安全特性:密码加密、敏感信息脱敏、请求频率限制
  6. 多 ORG 类型支持:支持 source 和 target 两种 ORG 类型

模块架构

整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                    Controller 层                          │
│  ┌──────────────────┐  ┌──────────────────┐           │
│  │ LoginController  │  │ HistoryController│           │
│  └────────┬─────────┘  └──────────────────┘           │
└───────────┼──────────────────────────────────────────────────┘
            │
┌───────────┼──────────────────────────────────────────────────┐
│           │              Service 层                         │
│  ┌────────┴────────┐  ┌──────────────────┐           │
│  │ LoginService     │  │ HistoryService   │           │
│  └────────┬────────┘  └──────────────────┘           │
└───────────┼──────────────────────────────────────────────────┘
            │
┌───────────┼──────────────────────────────────────────────────┐
│           │         Strategy 层(策略模式)                 │
│  ┌────────┴────────┐  ┌──────────────────┐           │
│  │StrategyFactory   │  │ LoginStrategy    │           │
│  └────────┬────────┘  └────────┬─────────┘           │
│           │                    │                       │
│  ┌────────┴──────────────────┴─────────┐           │
│  │  LegacyCredential │ OAuth2 │ CLI │ SessionId│    │
│  └──────────────────────────────────────┘           │
└──────────────────────────────────────────────────────────┘
            │
┌───────────┼──────────────────────────────────────────────────┐
│           │              Factory 层(工厂模式)               │
│  ┌────────┴────────┐  ┌──────────────────┐           │
│  │SessionManager    │  │ConnectionFactory│           │
│  └─────────────────┘  └──────────────────┘           │
└──────────────────────────────────────────────────────────┘

分层说明

1. Controller 层

负责处理 HTTP 请求,提供 REST API 接口。

主要类

  • DataISfLoginController:登录控制器
  • DataiSfLoginHistoryController:登录历史控制器
  • DataiSfLoginSessionController:登录会话控制器

2. Service 层

负责业务逻辑处理,协调各个组件完成业务功能。

主要类

  • ISalesforceLoginService:登录服务接口
  • SalesforceLoginServiceImpl:登录服务实现
  • IDataiSfLoginHistoryService:登录历史服务接口
  • IDataiSfLoginSessionService:登录会话服务接口

3. Strategy 层(策略模式)

负责不同登录方式的实现,使用策略模式支持多种登录方式。

主要类

  • LoginStrategy:登录策略接口
  • LoginStrategyFactory:登录策略工厂
  • LegacyCredentialLoginStrategy:传统账密凭证登录策略
  • OAuth2LoginStrategyOAuth2 登录策略
  • SalesforceCliLoginStrategySalesforce CLI 登录策略
  • SessionIdLoginStrategySession ID 登录策略

4. Factory 层(工厂模式)

负责连接的创建和管理,使用工厂模式提供统一的连接获取接口。

主要类

  • SessionManager:会话管理器
  • ISalesforceConnectionFactory<T>:连接工厂接口
  • AbstractConnectionFactory<T>:连接工厂抽象基类

核心组件详解

1. SessionManager会话管理器

类路径: com.datai.auth.core.SessionManager

功能描述 负责管理 Salesforce 会话信息,提供 Session ID 和 Instance URL 的获取,支持会话有效性检查和自动重新登录。

核心方法

/**
 * 获取当前Salesforce会话信息
 * 如果会话无效,则自动尝试重新登录
 *
 * @param orgType ORG类型source/target
 * @return SalesforceLoginResult 会话信息
 */
public SalesforceLoginResult getCurrentLoginResult(String orgType)

/**
 * 获取SessionId
 *
 * @param orgType ORG类型source/target
 * @return 访问令牌
 */
public String getCurrentSession(String orgType)

/**
 * 获取实例URL
 *
 * @param orgType ORG类型source/target
 * @return 实例URL
 */
public String getInstanceUrl(String orgType)

/**
 * 判断当前会话信息是否有效
 *
 * @param orgType ORG类型source/target
 * @return 如果会话有效返回true否则返回false
 */
public boolean isSessionValid(String orgType)

特性

  • 自动 Session 有效性检查
  • Session 过期时自动重新登录
  • 支持 source 和 target 两种 ORG 类型
  • 提前 5 分钟判断为过期,预留网络传输时间

2. ISalesforceConnectionFactory连接工厂接口

类路径: com.datai.auth.factory.ISalesforceConnectionFactory<T>

功能描述 定义所有 Salesforce 连接工厂的统一接口,提供连接获取、清除缓存等功能。

核心方法

/**
 * 获取连接实例
 * 如果缓存中没有有效的连接,则创建新的连接
 *
 * @param orgType ORG 类型source 或 target
 * @return 连接实例
 */
T getConnection(String orgType)

/**
 * 清除缓存的连接
 * 从缓存中移除连接实例
 *
 * @param orgType ORG 类型source 或 target
 */
void clearConnection(String orgType)

/**
 * 获取连接类型名称
 *
 * @return 连接类型名称
 */
String getConnectionType()

3. AbstractConnectionFactory连接工厂抽象基类

类路径: com.datai.auth.factory.AbstractConnectionFactory<T>

功能描述 提供通用的连接缓存和管理逻辑,使用模板方法模式,子类只需实现 createConnection 方法。

核心方法

/**
 * 获取连接实例
 * 自动处理连接缓存和 Session 有效性检查
 *
 * @param orgType ORG 类型source 或 target
 * @return 连接实例
 */
@Override
public T getConnection(String orgType)

/**
 * 创建连接(抽象方法,由子类实现)
 *
 * @param orgType ORG 类型
 * @return 连接实例
 */
protected abstract T createConnection(String orgType)

/**
 * 清除缓存的连接
 *
 * @param orgType ORG 类型
 */
@Override
public void clearConnection(String orgType)

特性

  • 连接缓存:使用 ConcurrentHashMap 缓存连接
  • 自动 Session 检查Session 过期时自动清除缓存
  • 线程安全:使用 ReentrantLock 保证多线程安全
  • 模板方法模式:子类只需实现 createConnection 方法

4. LoginStrategy登录策略接口

类路径: com.datai.auth.strategy.LoginStrategy

功能描述 定义不同登录方式的通用方法,支持策略模式。

核心方法

/**
 * 执行登录操作
 *
 * @param request 登录请求
 * @return 登录结果
 */
SalesforceLoginResult login(SalesforceLoginRequest request)

/**
 * 刷新Session
 *
 * @param refreshToken 刷新Session
 * @param loginType 登录类型
 * @return 新的登录结果
 */
SalesforceLoginResult refreshToken(String refreshToken, String loginType)

/**
 * 执行登出操作
 *
 * @param sessionId Session ID
 * @param loginType 登录类型
 * @return 登出是否成功
 */
boolean logout(String sessionId, String loginType)

/**
 * 获取登录类型
 *
 * @return 登录类型
 */
String getLoginType()

5. LoginStrategyFactory登录策略工厂

类路径: com.datai.auth.strategy.LoginStrategyFactory

功能描述 负责根据登录类型创建对应的登录策略,使用工厂模式。

核心方法

/**
 * 根据登录类型获取对应的登录策略
 *
 * @param loginType 登录类型
 * @return 登录策略实现
 */
public LoginStrategy getLoginStrategy(String loginType)

/**
 * 获取所有支持的登录类型
 *
 * @return 支持的登录类型列表
 */
public List<String> getSupportedLoginTypes()

支持的登录类型

  • legacy_credential:传统账密凭证登录
  • oauth2OAuth2 登录
  • salesforce_cliSalesforce CLI 登录
  • session_idSession ID 登录

6. LegacyCredentialLoginStrategy传统账密凭证登录策略

类路径: com.datai.auth.strategy.impl.LegacyCredentialLoginStrategy

功能描述 支持使用用户名、密码和安全令牌进行登录,使用 SOAP 登录方式。

核心流程

  1. 验证请求参数(用户名、密码)
  2. 获取 Salesforce 配置API 版本、环境类型、端点 URL 等)
  3. 构建 SOAP 登录请求
  4. 发送 SOAP 请求到 Salesforce
  5. 解析 SOAP 响应,提取 Session ID 和 Instance URL
  6. 返回登录结果

特性

  • 使用 SOAP 协议进行登录
  • 支持自定义登录 URL
  • 自动处理 API 版本和端点 URL
  • XML 转义防止注入攻击
  • 友好的错误消息(中文)
  • 连接超时处理

错误处理

  • LOGIN_MUST_USE_SECURITY_TOKEN:用户名、密码或安全标记无效,或用户被锁定
  • INVALID_LOGIN:用户名或密码错误
  • INVALID_OPERATION_WITH_EXPIRED_PASSWORD:密码已过期,请重置密码
  • USER_LOCKED_OUT:用户已被锁定,请联系管理员
  • PASSWORD_EXPIRED:密码已过期
  • SERVER_UNAVAILABLE:服务器暂时不可用,请稍后重试
  • API_DISABLED_FOR_ORG:组织的 API 访问已禁用

数据模型

SalesforceLoginRequest登录请求

类路径: com.datai.auth.model.domain.SalesforceLoginRequest

字段说明

字段名 类型 说明 必填
loginType String 登录类型oauth2、salesforce_cli、legacy_credential、session_id
username String 用户名
password String 密码
securityToken String 安全令牌
clientId String OAuth 客户端 ID
clientSecret String OAuth 客户端密钥
grantType String OAuth 授权类型
orgAlias String Salesforce CLI 组织别名
privateKeyPath String 私有密钥路径
privateKeyPassword String 私有密钥密码
code String OAuth 授权码
state String OAuth state 参数
sessionId String Session ID
loginUrl String 登录 URL
orgType String 组织类型source/target

SalesforceLoginResult登录结果

类路径: com.datai.auth.model.domain.SalesforceLoginResult

字段说明

字段名 类型 说明
success boolean 登录状态
errorCode String 错误代码
errorMessage String 错误消息
sessionId String Session ID
refreshToken String 刷新令牌(仅 OAuth 流程中存在)
tokenType String 令牌类型(默认为 "Bearer"
expiresIn long 过期时间(秒)
loginTimestamp long 登录时间戳
expirationTimestamp long 过期时间戳
instanceUrl String 实例 URL
metadataServerUrl String 元数据服务器 URL
sandbox boolean 是否为沙盒环境
passwordExpired boolean 密码是否已过期
userId String 用户 ID
organizationId String 组织 ID
orgType String 组织类型
userFullName String 用户全名
userEmail String 用户邮箱
organizationName String 组织名称
language String 语言
timeZone String 时区

核心方法

/**
 * 判断 sessionId 是否有效(基于本地时间估算)
 * 提前 5 分钟判断为过期,以预留网络传输时间
 */
public boolean isSessionExpired()

DataiSfLoginHistory登录历史

类路径: com.datai.auth.model.domain.DataiSfLoginHistory

功能描述 记录用户的登录历史包括登录时间、登录类型、Session ID 等信息。

主要字段

  • id主键
  • loginType登录类型
  • username用户名
  • sessionIdResultSession ID加密存储
  • instanceUrl实例 URL
  • userId用户 ID
  • organizationId组织 ID
  • orgType组织类型
  • loginTime登录时间
  • status登录状态success/failed
  • errorMessage错误消息
  • createTime创建时间

DataiSfLoginSession登录会话

类路径: com.datai.auth.model.domain.DataiSfLoginSession

功能描述 记录用户的登录会话信息,用于会话管理和查询。

主要字段

  • id主键
  • sessionIdSession ID
  • userId用户 ID
  • orgType组织类型
  • loginTime登录时间
  • lastAccessTime最后访问时间
  • expireTime过期时间
  • status会话状态active/expired
  • createTime创建时间

REST API 接口

1. 执行登录操作

接口: POST /salesforce/login/doLogin

功能: 执行 Salesforce 登录操作,支持多种登录方式

请求参数:

{
  "loginType": "legacy_credential",
  "username": "user@example.com",
  "password": "password",
  "securityToken": "token",
  "orgType": "source"
}

响应示例:

{
  "code": 200,
  "message": "登录成功",
  "data": {
    "success": true,
    "sessionId": "00Dxx0000001Gw2!AQ0AQH...",
    "instanceUrl": "https://yourorg.my.salesforce.com",
    "userId": "005xx0000001Gw2EAS",
    "organizationId": "00Dxx0000001Gw2EAS",
    "orgType": "source",
    "userFullName": "John Doe",
    "userEmail": "john.doe@example.com",
    "organizationName": "Your Organization",
    "language": "en_US",
    "timeZone": "America/Los_Angeles"
  }
}

2. 执行登出操作

接口: POST /salesforce/login/logout

功能: 执行 Salesforce 登出操作,清除本地缓存的 Session 信息

响应示例:

{
  "code": 200,
  "message": "登出成功",
  "data": null
}

3. 获取登录历史

接口: GET /salesforce/login/history

功能: 查询登录历史记录

响应示例:

{
  "code": 200,
  "message": "查询成功",
  "data": [
    {
      "id": 1,
      "loginType": "legacy_credential",
      "username": "user@example.com",
      "loginTime": "2026-01-28 10:00:00",
      "status": "success",
      "orgType": "source"
    }
  ]
}

4. 获取登录会话

接口: GET /salesforce/login/session

功能: 查询当前登录会话信息

响应示例:

{
  "code": 200,
  "message": "查询成功",
  "data": {
    "sessionId": "00Dxx0000001Gw2!AQ0AQH...",
    "userId": "005xx0000001Gw2EAS",
    "orgType": "source",
    "loginTime": "2026-01-28 10:00:00",
    "lastAccessTime": "2026-01-28 10:30:00",
    "expireTime": "2026-01-28 11:00:00",
    "status": "active"
  }
}

依赖关系

Maven 依赖

<dependencies>
    <!-- datai-salesforce-setting配置管理 -->
    <dependency>
        <groupId>com.datai</groupId>
        <artifactId>datai-salesforce-setting</artifactId>
    </dependency>

    <!-- datai-cache-redisRedis 缓存 -->
    <dependency>
        <groupId>com.datai</groupId>
        <artifactId>datai-cache-redis</artifactId>
        <version>${datai.version}</version>
    </dependency>

    <!-- jakarta.xml.soap-apiSOAP API -->
    <dependency>
        <groupId>jakarta.xml.soap</groupId>
        <artifactId>jakarta.xml.soap-api</artifactId>
        <version>3.0.0</version>
    </dependency>

    <!-- saaj-implSAAJ 实现 -->
    <dependency>
        <groupId>com.sun.xml.messaging.saaj</groupId>
        <artifactId>saaj-impl</artifactId>
        <version>3.0.2</version>
    </dependency>

    <!-- commons-textApache Commons Text -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-text</artifactId>
        <version>1.10.0</version>
    </dependency>

    <!-- jbcryptBCrypt 密码加密 -->
    <dependency>
        <groupId>org.mindrot</groupId>
        <artifactId>jbcrypt</artifactId>
        <version>0.4</version>
    </dependency>
</dependencies>

模块依赖

被依赖的模块

  • datai-salesforce-partner使用 SessionManager 和连接工厂
  • datai-salesforce-apex使用 SessionManager 和连接工厂
  • datai-salesforce-metadata使用 SessionManager 和连接工厂
  • datai-salesforce-tooling使用 SessionManager 和连接工厂

依赖的模块

  • datai-salesforce-setting配置管理
  • datai-cache-redisRedis 缓存
  • datai-salesforce-common通用工具和异常类

设计模式

1. 策略模式Strategy Pattern

应用场景:登录策略

实现方式

  • LoginStrategy 接口定义登录策略的通用方法
  • LegacyCredentialLoginStrategyOAuth2LoginStrategySalesforceCliLoginStrategySessionIdLoginStrategy 实现具体的登录策略
  • LoginStrategyFactory 负责根据登录类型创建对应的策略

优势

  • 支持多种登录方式,易于扩展新的登录方式
  • 每种登录方式独立实现,互不影响
  • 符合开闭原则(对扩展开放,对修改关闭)

2. 工厂模式Factory Pattern

应用场景:连接工厂

实现方式

  • ISalesforceConnectionFactory<T> 接口定义连接工厂的通用方法
  • AbstractConnectionFactory<T> 抽象类提供连接缓存和管理逻辑
  • 具体的连接工厂(如 PartnerConnectionFactory)继承 AbstractConnectionFactory 并实现 createConnection 方法

优势

  • 统一的连接创建和管理接口
  • 支持连接缓存,提高性能
  • 自动 Session 有效性检查
  • 线程安全的连接获取
  • 易于扩展新的连接类型

3. 模板方法模式Template Method Pattern

应用场景:连接工厂抽象基类

实现方式

  • AbstractConnectionFactory<T> 定义连接获取的模板方法
  • getConnection 方法定义连接获取的流程(检查缓存、检查 Session 有效性、创建连接)
  • createConnection 抽象方法由子类实现具体的连接创建逻辑

优势

  • 定义算法骨架,子类实现具体步骤
  • 复用公共逻辑缓存、Session 检查)
  • 子类只需关注自己的实现细节

安全特性

1. 密码加密

  • 使用 BCrypt 哈希算法加密存储密码
  • 密码无法直接解密,只能验证

2. 敏感信息脱敏

  • Session ID 在日志中会被脱敏处理
  • 不会记录完整的 Session ID

3. 请求频率限制

  • 登录接口有请求频率限制
  • 每分钟最多 5 次登录尝试

4. XML 转义

  • 使用 Apache Commons Text 的 StringEscapeUtils.escapeXml11() 进行 XML 转义
  • 防止 XML 注入攻击

5. 连接超时处理

  • 连接超时时间10 秒
  • 读取超时时间30 秒

配置说明

环境配置

配置存储在 Redis 缓存中,通过 SalesforceConfigCacheManager 管理。

主要配置项

配置项 说明 默认值
salesforce.api.version API 版本 65.0
salesforce.environment.type 环境类型production/sandbox/custom production
salesforce.api.namespace API 命名空间 urn:partner.soap.sforce.com
salesforce.api.endpoint.production 生产环境端点 https://login.salesforce.com
salesforce.api.endpoint.sandbox 沙盒环境端点 https://test.salesforce.com
salesforce.api.endpoint.custom 自定义环境端点 -

使用示例

示例 1使用 SessionManager 获取会话信息

@Autowired
private SessionManager sessionManager;

public void example() {
    // 获取当前会话信息
    SalesforceLoginResult result = sessionManager.getCurrentLoginResult("source");
    
    if (result.isSuccess()) {
        String sessionId = result.getSessionId();
        String instanceUrl = result.getInstanceUrl();
        System.out.println("Session ID: " + sessionId);
        System.out.println("Instance URL: " + instanceUrl);
    }
}

示例 2实现 PartnerConnectionFactory

@Component
public class PartnerConnectionFactory extends AbstractConnectionFactory<PartnerConnection> {

    @Override
    protected PartnerConnection createConnection(String orgType) {
        try {
            // 获取 Session ID 和 Instance URL
            String sessionId = sessionManager.getCurrentSession(orgType);
            String instanceUrl = sessionManager.getInstanceUrl(orgType);
            
            // 创建 ConnectorConfig
            ConnectorConfig config = new ConnectorConfig();
            config.setSessionId(sessionId);
            config.setRestEndpoint(instanceUrl);
            
            // 创建 PartnerConnection
            return new PartnerConnection(config);
        } catch (ConnectionException e) {
            throw new RuntimeException("创建 PartnerConnection 失败", e);
        }
    }
}

示例 3使用连接工厂获取连接

@Autowired
private PartnerConnectionFactory partnerConnectionFactory;

public void example() {
    // 获取 PartnerConnection自动处理缓存和 Session 有效性检查)
    PartnerConnection connection = partnerConnectionFactory.getConnection("source");
    
    // 使用连接执行操作
    try {
        QueryResult result = connection.query("SELECT Id, Name FROM Account LIMIT 10");
        // 处理结果
    } catch (ConnectionException e) {
        // 处理异常
    }
}

最佳实践

1. 使用 SessionManager 管理会话

  • 始终通过 SessionManager 获取会话信息
  • 不要直接使用缓存的 Session ID
  • SessionManager 会自动处理 Session 过期和重新登录

2. 使用连接工厂获取连接

  • 始终通过连接工厂获取连接
  • 不要手动创建和管理连接
  • 连接工厂会自动处理连接缓存和 Session 有效性检查

3. 处理异常

  • 捕获并处理 ConnectionException
  • 捕获并处理 ApiFault
  • 使用 datai-salesforce-common 模块中的异常类
  • 返回友好的错误消息

4. 日志记录

  • 记录关键操作(登录、登出、获取会话等)
  • 敏感信息(如 Session ID需要脱敏处理
  • 使用合适的日志级别INFO、WARN、ERROR

5. 性能优化

  • 使用连接缓存,避免重复创建连接
  • 使用 Redis 缓存配置信息
  • 合理设置连接超时时间

常见问题

Q1Session 过期后如何处理?

ASessionManager 会自动检测 Session 过期,并自动调用 autoLogin 方法重新登录。开发者无需手动处理。

Q2如何支持新的登录方式

A实现 LoginStrategy 接口,创建新的登录策略类,并使用 @Component 注解。LoginStrategyFactory 会自动发现并注册新的策略。

Q3如何清除缓存的连接

A调用连接工厂的 clearConnection 方法,传入 orgType 参数即可清除对应类型的连接缓存。

Q4如何区分 source 和 target ORG

A通过 orgType 参数区分,"source" 表示源 ORG"target" 表示目标 ORG。SessionManager 和连接工厂都支持 orgType 参数。

Q5密码如何加密存储

A使用 BCrypt 哈希算法加密存储密码。密码无法直接解密,只能通过验证方式确认密码正确性。

总结

datai-salesforce-auth 模块是整个 Salesforce 集成体系的基础,提供了统一的认证和会话管理能力。通过策略模式支持多种登录方式,通过工厂模式提供统一的连接管理接口,具有良好的扩展性和可维护性。

核心优势

  1. 统一的认证和会话管理
  2. 支持多种登录方式
  3. 自动 Session 有效性检查
  4. 连接缓存和线程安全
  5. 良好的扩展性
  6. 完善的安全特性

适用场景

  • 需要与 Salesforce 集成的应用
  • 需要多种登录方式支持
  • 需要统一的会话管理
  • 需要高性能的连接管理