248 lines
7.6 KiB
Markdown
248 lines
7.6 KiB
Markdown
# ADR-003-02: Salesforce 策略模式登录架构决策
|
||
|
||
## 元数据
|
||
- ADR 编号:ADR-003-02
|
||
- 需求编号:2026-01-21-003-02
|
||
- 创建时间:2026-01-22
|
||
- 状态:已采纳
|
||
- 决策人:SSOT 架构师
|
||
|
||
## 背景和问题陈述
|
||
|
||
### 背景
|
||
Salesforce 多系统认证功能需要支持多种登录方式,包括 OAuth2 Password 登录、OAuth2 Client Credentials 登录、OAuth2 Authorization Code 登录、Session ID 登录。用户需要能够通过页面选择登录策略,系统需要支持扩展新的登录策略。
|
||
|
||
### 问题
|
||
1. 如何实现多种登录方式的灵活切换?
|
||
2. 如何支持用户选择登录策略?
|
||
3. 如何支持扩展新的登录策略?
|
||
4. 如何管理登录策略的依赖注入?
|
||
|
||
## 决策驱动因素
|
||
|
||
### 技术因素
|
||
1. **扩展性**:需要支持未来新增登录策略
|
||
2. **可维护性**:代码结构清晰,易于维护
|
||
3. **灵活性**:支持用户选择登录策略
|
||
4. **解耦性**:登录策略与业务逻辑解耦
|
||
|
||
### 业务因素
|
||
1. **用户体验**:用户可以方便地选择登录策略
|
||
2. **功能完整**:支持 OAuth2 Password、OAuth2 Client Credentials、OAuth2 Authorization Code、Session ID 四种登录方式
|
||
3. **未来扩展**:预留接口支持新的登录策略
|
||
|
||
### 非功能因素
|
||
1. **性能**:登录响应时间 < 3 秒
|
||
2. **安全**:敏感信息加密存储,HTTPS 传输
|
||
3. **可用性**:系统可用性 99.9%
|
||
|
||
## 考虑的选项
|
||
|
||
### 选项 1:使用策略模式 + 工厂方法模式
|
||
|
||
#### 描述
|
||
使用策略模式实现不同登录策略,使用工厂方法模式进行依赖注入。
|
||
|
||
#### 优点
|
||
1. 符合开闭原则,对扩展开放,对修改关闭
|
||
2. 策略之间相互独立,互不影响
|
||
3. 工厂方法模式管理策略实例,便于依赖注入
|
||
4. 代码结构清晰,易于理解和维护
|
||
5. 支持运行时动态选择策略
|
||
|
||
#### 缺点
|
||
1. 需要定义策略接口和多个策略实现
|
||
2. 增加了类的数量
|
||
3. 需要额外的工厂类
|
||
|
||
#### 影响
|
||
- 代码复杂度:中等
|
||
- 性能影响:低
|
||
- 可维护性:高
|
||
- 扩展性:高
|
||
|
||
### 选项 2:使用 if-else 条件判断
|
||
|
||
#### 描述
|
||
使用 if-else 条件判断不同的登录类型,执行对应的登录逻辑。
|
||
|
||
#### 优点
|
||
1. 实现简单,代码量少
|
||
2. 不需要额外的类和接口
|
||
|
||
#### 缺点
|
||
1. 违反开闭原则,新增登录策略需要修改现有代码
|
||
2. 代码耦合度高,难以维护
|
||
3. 不支持运行时动态选择策略
|
||
4. 代码可读性差,if-else 嵌套多
|
||
|
||
#### 影响
|
||
- 代码复杂度:低
|
||
- 性能影响:低
|
||
- 可维护性:低
|
||
- 扩展性:低
|
||
|
||
### 选项 3:使用状态模式
|
||
|
||
#### 描述
|
||
使用状态模式管理登录状态,不同状态对应不同的登录策略。
|
||
|
||
#### 优点
|
||
1. 状态转换清晰
|
||
2. 支持状态相关的行为
|
||
|
||
#### 缺点
|
||
1. 状态模式适用于状态转换场景,不适合登录策略选择
|
||
2. 增加了不必要的复杂性
|
||
3. 不符合业务场景
|
||
|
||
#### 影响
|
||
- 代码复杂度:高
|
||
- 性能影响:低
|
||
- 可维护性:中
|
||
- 扩展性:中
|
||
|
||
## 决策结果
|
||
|
||
### 选择的方案
|
||
**选项 1:使用策略模式 + 工厂方法模式**
|
||
|
||
### 决策理由
|
||
1. **扩展性**:策略模式支持新增登录策略,符合开闭原则
|
||
2. **可维护性**:代码结构清晰,策略之间相互独立
|
||
3. **灵活性**:工厂方法模式管理策略实例,支持运行时动态选择
|
||
4. **解耦性**:登录策略与业务逻辑解耦
|
||
5. **符合业务场景**:用户选择登录策略的场景适合使用策略模式
|
||
|
||
### 拒绝其他方案的理由
|
||
1. **拒绝选项 2**:if-else 条件判断违反开闭原则,不利于扩展
|
||
2. **拒绝选项 3**:状态模式不适合登录策略选择的场景
|
||
|
||
## 决策细节
|
||
|
||
### 策略接口设计
|
||
```java
|
||
public interface LoginStrategy {
|
||
|
||
LoginResult login(LoginRequest request) throws LoginException;
|
||
|
||
LoginResult refreshToken(RefreshTokenRequest request) throws RefreshTokenException;
|
||
|
||
void logout(LogoutRequest request) throws LoginException;
|
||
|
||
String getLoginType();
|
||
|
||
boolean supportRefreshToken();
|
||
}
|
||
```
|
||
|
||
### 策略实现
|
||
1. **OAuth2LoginStrategy**:实现 OAuth2 登录策略
|
||
2. **SessionIdLoginStrategy**:实现 Session ID 登录策略
|
||
3. **预留接口**:支持扩展新的登录策略
|
||
|
||
### 工厂方法设计
|
||
```java
|
||
@Component
|
||
public class LoginStrategyFactory {
|
||
|
||
private final Map<String, LoginStrategy> strategyMap;
|
||
|
||
@Autowired
|
||
public LoginStrategyFactory(List<LoginStrategy> strategies) {
|
||
this.strategyMap = strategies.stream()
|
||
.collect(Collectors.toMap(LoginStrategy::getLoginType, Function.identity()));
|
||
}
|
||
|
||
public LoginStrategy getStrategy(String loginType) {
|
||
LoginStrategy strategy = strategyMap.get(loginType);
|
||
if (strategy == null) {
|
||
throw new IllegalArgumentException("不支持的登录类型: " + loginType);
|
||
}
|
||
return strategy;
|
||
}
|
||
|
||
public List<String> getSupportedLoginTypes() {
|
||
return new ArrayList<>(strategyMap.keySet());
|
||
}
|
||
|
||
public void registerStrategy(String loginType, LoginStrategy strategy) {
|
||
strategyMap.put(loginType, strategy);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 依赖注入方式
|
||
使用 Spring 的依赖注入机制,通过 `@Autowired` 注入 `List<LoginStrategy>`,工厂类自动收集所有策略实现。
|
||
|
||
## 后果
|
||
|
||
### 正面后果
|
||
1. **扩展性**:新增登录策略只需实现 LoginStrategy 接口,无需修改现有代码
|
||
2. **可维护性**:策略之间相互独立,易于维护和测试
|
||
3. **灵活性**:工厂方法模式支持运行时动态选择策略
|
||
4. **解耦性**:登录策略与业务逻辑解耦,降低耦合度
|
||
5. **代码质量**:符合设计模式最佳实践,代码结构清晰
|
||
|
||
### 负面后果
|
||
1. **类数量增加**:需要定义策略接口、多个策略实现和工厂类
|
||
2. **学习成本**:需要理解策略模式和工厂方法模式
|
||
3. **初始化复杂度**:工厂类需要收集和管理所有策略实例
|
||
|
||
### 风险
|
||
1. **策略实例管理**:需要确保策略实例正确初始化和管理
|
||
2. **异常处理**:需要统一处理策略执行过程中的异常
|
||
3. **性能考虑**:频繁创建策略实例可能影响性能
|
||
|
||
## 实施计划
|
||
|
||
### 阶段 1:策略接口和工厂实现
|
||
1. 定义 LoginStrategy 接口
|
||
2. 实现 LoginStrategyFactory 工厂类
|
||
3. 配置 Spring 依赖注入
|
||
|
||
### 阶段 2:OAuth2 登录策略实现
|
||
1. 实现 OAuth2LoginStrategy 类
|
||
2. 实现登录、刷新令牌、登出方法
|
||
3. 集成 Salesforce OAuth2 API
|
||
|
||
### 阶段 3:Session ID 登录策略实现
|
||
1. 实现 SessionIdLoginStrategy 类
|
||
2. 实现登录、登出方法
|
||
3. 集成 Salesforce Identity API
|
||
|
||
### 阶段 4:服务层和控制器实现
|
||
1. 实现 ISalesforceAuthService 接口
|
||
2. 实现 SalesforceAuthServiceImpl 服务类
|
||
3. 实现 SalesforceAuthController 控制器类
|
||
|
||
### 阶段 5:测试和优化
|
||
1. 编写单元测试
|
||
2. 编写集成测试
|
||
3. 性能优化
|
||
|
||
## 监控和评估
|
||
|
||
### 监控指标
|
||
1. **登录成功率**:监控登录成功率,目标 ≥ 95%
|
||
2. **登录响应时间**:监控登录响应时间,目标 < 3 秒
|
||
3. **异常率**:监控登录异常率,目标 < 5%
|
||
|
||
### 评估周期
|
||
1. **短期评估**:上线后 1 周内评估
|
||
2. **中期评估**:上线后 1 个月内评估
|
||
3. **长期评估**:上线后 3 个月内评估
|
||
|
||
### 评估标准
|
||
1. **功能完整性**:所有功能点是否实现
|
||
2. **性能指标**:是否达到性能目标
|
||
3. **用户体验**:用户反馈是否良好
|
||
4. **扩展性**:是否易于扩展新的登录策略
|
||
|
||
## 相关决策
|
||
- ADR-003-01: Salesforce 多系统配置架构决策
|
||
|
||
## 相关文档
|
||
- [需求文档](../requirements/2026-01-21-003-02-salesforce-strategy-login.md)
|
||
- [设计文档](../design/2026-01-21-003-02-salesforce-strategy-login-design.md)
|