邮箱:wei_wei10@163.com
微信:wei_wei10
音频地址:https://xima.tv/1_YPIE2Yn?_sonic=0
希望大家帮个忙!如果大家有工作机会,希望帮小蒋内推一下,小蒋希望遇到一个认真做事的团队,一起努力。需要简历可以加我微信。
大家好,欢迎来到小蒋聊技术,小蒋准备和大家一起聊聊技术的那些事。
今天小蒋准备和大家一起聊的这个技术就厉害了!那就是动态权限管理的设计。
1. 需求分析
在证券交易系统中,数据通常会经历多个生命周期阶段,如草稿、预成交、成交、复核等。每个阶段可能对应不同的操作权限需求。例如,在草稿阶段,只有录入员可以创建和修改数据;在复核阶段,只有特定的审核员可以执行审批操作。基于此,系统需要设计一个动态的认证与鉴权模块,能够根据数据的生命周期动态管理用户权限。
结合提供的ER图,我们可以看到系统中涉及的实体及其关系。需要特别注意的是,系统的各类交易(如BOND_TR、BOND等)均涉及多种业务流程和数据状态,因此系统必须能够动态处理这些数据状态,并相应调整用户的权限。
主要需求:
- 动态权限管理:系统必须支持根据用户角色和数据当前的生命周期状态动态进行权限检查。
- 模块化设计:权限管理模块与业务逻辑模块完全独立,确保高内聚低耦合。
- 生命周期管理:数据在不同的生命周期阶段具有不同的权限要求,系统需要支持这种状态驱动的权限管理。
- 微服务架构:系统采用微服务架构,需要使用API Gateway、Nacos等进行服务注册与发现。
- 可扩展性:系统应能够通过配置或数据库动态调整权限规则,以适应业务需求的变化。
2. 设计思路
为了满足上述需求,设计思路将围绕以下几个核心点展开:
- 基于Spring Security OAuth2的认证与鉴权:利用Spring Security OAuth2提供的身份验证和授权机制,结合JWT令牌实现用户身份和权限的分布式管理。
- 动态权限检查机制:权限检查逻辑应独立于业务逻辑,并且根据数据的生命周期状态和用户的角色进行动态评估。通过策略模式、责任链模式等设计模式实现权限逻辑的可配置和可扩展性。
- 生命周期驱动的权限管理:引入数据生命周期的概念,权限规则根据数据的当前状态进行动态配置和调整。使用LifecycleStatePermissions表存储各生命周期阶段的权限配置。
- 微服务架构与服务发现:通过Spring Cloud Gateway作为统一入口,使用Nacos进行服务注册与发现,确保系统的扩展性和可管理性。
- 操作审计与日志记录:通过AOP实现操作日志的记录,确保系统的安全性和可追溯性。
3. 方案设计
3.1 系统架构概述
- API Gateway(Spring Cloud Gateway):
- 职责:作为系统的统一入口,处理所有外部请求,进行初步的身份认证,并将请求路由到合适的微服务。
- 功能:执行基于OAuth2的身份验证,获取并验证JWT令牌,传递令牌和用户信息给后端服务,实现全局的用户身份管理。
- OAuth2 Authorization Server:
- 职责:管理用户的身份认证和授权,生成并签发JWT令牌。
- 功能:用户登录后生成JWT令牌,并通过API Gateway传递给客户端。提供统一的用户认证和授权服务,确保系统的安全性。
- API服务:
- 职责:提供用户信息和权限管理服务,供其他微服务调用。
- 功能:提供用户信息和权限查询接口,动态管理用户权限,确保根据业务需求实时调整权限配置。
- 权限管理模块:
- 职责:独立于业务逻辑的权限检查服务,在业务方法执行前动态检查用户的操作权限。
- 功能:动态加载权限规则,确保不同业务场景下的灵活性。通过配置文件或数据库实现权限逻辑的动态配置,支持不同生命周期状态下的权限管理。
- 业务服务模块:
- 职责:处理具体的业务逻辑,实现核心业务功能。
- 功能:专注于业务逻辑实现,不包含任何权限检查逻辑。在执行业务方法前,通过调用权限管理模块进行权限检查。
- Nacos 服务注册与发现:
- 职责:管理系统中各个微服务的注册与发现,确保服务的动态扩展。
- 功能:通过Nacos进行服务注册,支持系统的自动扩展和负载均衡。提供服务健康检查和配置管理功能,增强系统的可靠性。
- 操作审计与日志记录:
- 职责:通过AOP实现操作审计和日志记录,确保系统操作的可追溯性。
- 功能:记录系统的关键操作和用户行为,形成完整的审计日志。支持日志的动态配置,确保系统运行状态的透明性和可追溯性。
3.2 动态权限检查与生命周期管理
- LifecycleStatePermissions表:
- 功能:存储数据在不同生命周期阶段的角色权限配置,用于在权限检查时动态评估用户的操作权限。
- 字段设计:
- State: 数据的生命周期状态(如草稿、复核等)。
- RoleId: 用户角色ID。
- Permission: 允许的操作权限(如创建、修改、审批等)。
- 权限检查逻辑:
- 设计模式:采用策略模式和责任链模式,实现权限检查逻辑的动态加载和执行。
- 实现:
- 在业务方法执行前,系统调用权限管理模块,通过当前数据的生命周期状态和用户角色动态选择合适的权限策略进行权限检查。
- 如果用户具备所需的权限,则允许业务方法执行;否则,拒绝操作并返回相应的错误信息。
public class PermissionService {
@Autowired
private LifecycleStatePermissionsRepository permissionsRepository;
public boolean checkPermission(UserInfo userInfo, Bond bond, String action) {
BondState state = bond.getState();
String roleId = userInfo.getRoleId();
return permissionsRepository.existsByStateAndRoleAndPermission(state, roleId, action);
}
}
3.3 具体实现示例
Spring Security配置:
@EnableWebSecurity
public class ResourceServerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/bonds/create").access("@dynamicAuthService.checkPermission(authentication, 'CREATE')")
.antMatchers(HttpMethod.PUT, "/bonds/edit/**").access("@dynamicAuthService.checkPermission(authentication, 'EDIT')")
.antMatchers(HttpMethod.GET, "/bonds/view/**").access("@dynamicAuthService.checkPermission(authentication, 'VIEW')")
.antMatchers(HttpMethod.POST, "/bonds/approve/**").access("@dynamicAuthService.checkPermission(authentication, 'REVIEW')")
.anyRequest().authenticated()
.and()
.oauth2ResourceServer()
.jwt();
}
}
动态权限检查服务:
@Service("dynamicAuthService")
public class DynamicAuthService {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LifecycleStatePermissionsRepository permissionsRepository;
public boolean checkPermission(Authentication authentication, String action) {
// 获取用户信息
ResponseEntity<UserInfo> response = restTemplate.getForEntity("http://API-SERVICE/api/user/info", UserInfo.class);
UserInfo userInfo = response.getBody();
// 根据用户信息和数据状态进行权限检查
return permissionsRepository.existsByStateAndRoleAndPermission(userInfo.getCurrentState(), userInfo.getRoleId(), action);
}
}
3.4 数据库设计
结合ER图中的实体和认证/鉴权需求,设计以下关键数据库表:
- Users 表:
- 字段:
- UserId:主键,唯一标识用户。
- Username:用户名,用于登录。
- Password:用户密码,经过加密存储。
- Enabled:用户是否被启用。
- 字段:
- Roles 表:
- 字段:
- RoleId:主键,唯一标识角色。
- RoleName:角色名称,如录入员、审核员等。
- 字段:
- Permissions 表:
- 字段:
- PermissionId:主键,唯一标识权限。
- PermissionName:权限名称,如创建、修改、审批等。
- 字段:
- UserRoles 表:
- 字段:
- UserId:外键,关联到Users表。
- RoleId:外键,关联到Roles表。
- 字段:
- LifecycleStatePermissions 表:
- 字段:
- State:数据当前的生命周期状态(如草稿、复核等)。
- RoleId:外键,关联到Roles表。
- PermissionId:外键,关联到Permissions表。
- 字段:
- AuditLogs 表:
- 字段:
- LogId:主键,唯一标识日志记录。
- UserId:外键,关联到Users表,记录执行操作的用户。
- Action:记录用户执行的操作。
- Timestamp:操作的时间戳。
- 字段:
4. 设计思路与必要实现
4.1 设计思路补充
- 微服务架构与松耦合设计:
- 系统通过Spring Cloud Gateway实现请求的统一入口,并通过Nacos实现各个微服务的注册与发现。微服务之间通过轻量级协议(如HTTP)进行通信,所有的服务都是松耦合的,服务之间的调用由配置或服务发现机制动态管理,避免了硬编码。
- 策略模式与责任链模式的结合使用:
- 使用策略模式为不同的权限检查逻辑创建可插拔的策略类。例如,不同的用户角色或不同的业务状态可以有各自的权限检查策略。
- 使用责任链模式将这些策略串联起来,形成灵活的权限检查流程。每个权限检查步骤都可以独立执行,也可以通过配置动态调整。
- 数据生命周期的灵活管理:
- 每个业务实体(如BOND_TR、BOND等)都可能具有复杂的生命周期状态,系统通过LifecycleStatePermissions表记录不同状态下的权限配置。系统在权限检查时,动态查询这些配置,确保用户操作符合当前数据状态的权限要求。
- 审计与日志:
- 所有关键操作都通过AOP记录到AuditLogs表,形成完整的操作日志。日志记录不仅有助于安全审计,还可以用于日后问题的追踪与分析。
4.2 必要实现补充
1.权限策略接口定义:
Copy code
public interface PermissionStrategy {
boolean hasPermission(UserInfo userInfo, Bond bond, String action);
}
2.具体策略实现:
public class DraftStatePermissionStrategy implements PermissionStrategy {
@Override
public boolean hasPermission(UserInfo userInfo, Bond bond, String action) {
return userInfo.hasRole("ROLE_INPUT") && action.equals("CREATE");
}
}
public class ReviewStatePermissionStrategy implements PermissionStrategy {
@Override
public boolean hasPermission(UserInfo userInfo, Bond bond, String action) {
return userInfo.hasRole("ROLE_REVIEWER") && action.equals("APPROVE");
}
}
3.策略工厂类:
public class PermissionStrategyFactory {
public static PermissionStrategy getStrategy(BondState state) {
switch (state) {
case DRAFT:
return new DraftStatePermissionStrategy();
case REVIEW:
return new ReviewStatePermissionStrategy();
default:
throw new IllegalArgumentException("Unknown state: " + state);
}
}
}
4.责任链模式的实现:
public abstract class PermissionHandler {
protected PermissionHandler nextHandler;
public void setNextHandler(PermissionHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract boolean handle(UserInfo userInfo, Bond bond, String action);
}
public class RoleCheckHandler extends PermissionHandler {
@Override
public boolean handle(UserInfo userInfo, Bond bond, String action) {
if (userInfo.hasRole("ROLE_ADMIN")) {
return true; // 管理员有全部权限
}
if (nextHandler != null) {
return nextHandler.handle(userInfo, bond, action);
}
return false;
}
}
public class StateCheckHandler extends PermissionHandler {
@Override
public boolean handle(UserInfo userInfo, Bond bond, String action) {
if (bond.getState() == BondState.DRAFT && action.equals("EDIT")) {
return userInfo.hasRole("ROLE_EDITOR");
}
if (nextHandler != null) {
return nextHandler.handle(userInfo, bond, action);
}
return false;
}
}
5.审计日志实现:
@Aspect
@Component
public class AuditAspect {
private static final Logger logger = LoggerFactory.getLogger(AuditAspect.class);
@AfterReturning(pointcut = "execution(* com.example.bond.BondService.*(..))", returning = "result")
public void logAfterMethod(JoinPoint joinPoint, Object result) {
String methodName = joinPoint.getSignature().getName();
logger.info("User performed operation: " + methodName + " with result: " + result);
// 可选:将日志记录存储到数据库,形成审计日志
// auditLogRepository.save(new AuditLog(methodName, result));
}
}
5. 方案总结
本方案通过设计一个基于Spring Security OAuth2的动态权限管理系统,支持数据的生命周期管理,确保在证券交易系统中,不同角色的用户能够根据其权限在不同的生命周期阶段进行合法的操作。通过微服务架构和设计模式的应用,系统在保持高内聚、低耦合的同时,也确保了高度的可扩展性和灵活性。结合提供的ER图,系统的各个模块可以无缝集成,从而满足复杂的业务需求。