iis架设网站教程,wordpress熊掌号插件,卖表网站源码,汕头网站推广费用#x1f3af; 权限管理组件执行流程详解
#x1f3d7;️ 组件架构图
┌─────────────────────────────────────────────────────────────┐
│ HTTP请求 … 权限管理组件执行流程详解
️ 组件架构图
┌─────────────────────────────────────────────────────────────┐
│ HTTP请求 │
└─────────────────────┬───────────────────────────────────────┘│
┌─────────────────────▼───────────────────────────────────────┐
│ SecureController │
│ - 获取当前用户ID │
│ - 统一错误处理 │
└─────────────────────┬───────────────────────────────────────┘│
┌─────────────────────▼───────────────────────────────────────┐
│ SecurityService (接口) │
│ - 业务语义化的权限检查方法 │
│ - canAccessUser(), canCreateProcurement()等 │
└─────────────────────┬───────────────────────────────────────┘│
┌─────────────────────▼───────────────────────────────────────┐
│ SecurityServiceImpl (实现) │
│ - 构建SecurityContext │
│ - 调用PermissionEngine │
│ - 异常处理 │
└─────────────────────┬───────────────────────────────────────┘│
┌─────────────────────▼───────────────────────────────────────┐
│ PermissionEngine (接口) │
│ - 权限计算的抽象接口 │
│ - checkPermission()方法 │
└─────────────────────┬───────────────────────────────────────┘│
┌─────────────────────▼───────────────────────────────────────┐
│ RoleBasedPermissionEngine (实现) │
│ - 具体的权限计算逻辑 │
│ - 基于角色的权限规则 │
└─────────────────────────────────────────────────────────────┘完整执行流程
场景BUYER用户想查看自己的信息
让我们跟踪一个完整的请求GET /api/v1/users/123
第1步SecureController - 安全控制器基类
// 任何继承SecureController的Controller
RestController
class UserController(currentUserService: CurrentUserService,private val securityService: SecurityService // 注入SecurityService接口
) : SecureController(currentUserService) {GetMapping(/api/v1/users/{userId})fun getUserInfo(PathVariable userId: String): ResponseEntityUserInfo {// 1.1 获取当前用户ID来自SecureController基类val currentUserId getCurrentUserId() // 返回 123// 1.2 调用SecurityService进行权限检查if (!securityService.canAccessUser(userId)) { // 调用接口方法return createForbiddenResponse()}// 1.3 执行业务逻辑val userInfo userService.getUserInfo(userId)return ResponseEntity.ok(userInfo)}
}SecureController说“我获取到当前用户ID是123现在要检查是否可以访问用户123的信息让我问问SecurityService”
第2步SecurityService - 权限服务接口
// SecurityService.kt - 接口定义
interface SecurityService {/*** 是否可以访问用户信息*/fun canAccessUser(userId: String?): Boolean // 业务语义化的方法/*** 是否可以创建采购需求*/fun canCreateProcurement(): Boolean// ... 其他业务权限方法
}SecurityService接口说“我定义了所有业务权限检查的方法具体实现由SecurityServiceImpl来完成”
第3步SecurityServiceImpl - 权限服务实现
// SecurityServiceImpl.kt - 具体实现
Service(securityService)
class SecurityServiceImpl(private val currentUserService: CurrentUserService,private val permissionEngine: PermissionEngine // 注入PermissionEngine接口
) : SecurityService {override fun canAccessUser(userId: String?): Boolean {// 3.1 调用通用权限检查方法return safeCheckPermission(user, read, userId) // 转换为通用格式}private fun safeCheckPermission(resource: String, // useraction: String, // readtargetId: String? // 123): Boolean {return try {// 3.2 构建安全上下文val context getCurrentSecurityContext() ?: return false// 3.3 调用权限引擎进行具体检查permissionEngine.checkPermission(context, resource, action, targetId) // 委托给引擎} catch (e: Exception) {false // 异常时拒绝访问}}private fun getCurrentSecurityContext(): SecurityContext? {return try {val currentUserResult currentUserService.getCurrentUser()if (!currentUserResult.isSuccess) return nullval currentUser currentUserResult.data!!val role Role.fromCode(currentUser.role.name) ?: return null// 3.4 创建SecurityContext对象SecurityContext(userId currentUser.id.value.toString(), // 123userRole role, // Role.BUYERuserStatus currentUser.status.name // ACTIVE)} catch (e: Exception) {null}}
}SecurityServiceImpl说“我收到canAccessUser请求让我构建安全上下文然后调用权限引擎来做具体判断”
第4步PermissionEngine - 权限引擎接口
// PermissionEngine.kt - 权限计算引擎接口
interface PermissionEngine {/*** 检查权限*/fun checkPermission(context: SecurityContext, // 安全上下文resource: String, // 资源类型action: String, // 操作类型targetId: String? null // 目标ID): Booleanfun getEngineVersion(): Stringfun getEngineDescription(): String
}PermissionEngine接口说“我定义了权限计算的标准接口具体的计算逻辑由不同的实现来完成”
第5步RoleBasedPermissionEngine - 基于角色的权限引擎
// RoleBasedPermissionEngine.kt - 具体的权限计算实现
Component
class RoleBasedPermissionEngine : PermissionEngine {override fun checkPermission(context: SecurityContext, // userId123, userRoleBUYER, userStatusACTIVEresource: String, // useraction: String, // readtargetId: String? // 123): Boolean {// 5.1 基础检查非活跃用户无权限if (!context.isActive()) {return false}// 5.2 管理员检查管理员拥有所有权限if (context.isAdmin()) {return true}// 5.3 根据角色进行具体权限检查return when (context.userRole) {Role.BUYER - checkBuyerPermission(context, resource, action, targetId) // BUYER角色Role.SELLER - checkSellerPermission(context, resource, action, targetId)Role.FORWARDER - checkForwarderPermission(context, resource, action, targetId)Role.SALES - checkSalesPermission(context, resource, action, targetId)Role.SUPPORT - checkSupportPermission(context, resource, action, targetId)Role.ADMIN - true // 已在上面处理}}private fun checkBuyerPermission(context: SecurityContext, // userId123, userRoleBUYERresource: String, // useraction: String, // readtargetId: String? // 123): Boolean {return when (resource) {user - when (action) {read - context.canAccessUserData(targetId) // 检查是否可以访问用户数据write - context.canAccessUserData(targetId)else - false}procurement - when (action) {create - true // BUYER可以创建采购需求read - true // BUYER可以查看采购需求write - canAccessOwnResource(context, targetId) // 只能修改自己的else - false}// ... 其他资源else - false}}
}RoleBasedPermissionEngine说“让我分析…用户123是BUYER角色想读取用户123的信息这是访问自己的数据允许”各组件的具体职责
1. SecureController安全控制器基类
// 职责提供安全基础设施
abstract class SecureController {protected fun getCurrentUserId(): String // 获取当前用户IDprotected fun resolveUserId(String?): String // 解析目标用户IDprotected fun createForbiddenResponse(): ResponseEntity // 创建403响应
}角色安全基础设施提供者
工作获取用户身份、统一错误处理
2. SecurityService权限服务接口
// 职责定义业务权限检查接口
interface SecurityService {fun canAccessUser(userId: String?): Boolean // 业务语义化fun canCreateProcurement(): Boolean // 业务语义化fun canModifyOrder(orderId: String?): Boolean // 业务语义化
}角色业务权限接口定义者
工作提供清晰的业务语义化权限检查方法
3. SecurityServiceImpl权限服务实现
// 职责协调和转换
Service
class SecurityServiceImpl {private fun safeCheckPermission(resource, action, targetId): Boolean // 转换格式private fun getCurrentSecurityContext(): SecurityContext // 构建上下文
}角色协调者和转换器
工作
将业务方法转换为通用权限检查构建SecurityContext异常处理委托给权限引擎
4. PermissionEngine权限引擎接口
// 职责定义权限计算接口
interface PermissionEngine {fun checkPermission(context, resource, action, targetId): Boolean // 通用权限检查
}角色权限计算接口定义者
工作定义标准的权限计算接口支持可插拔实现
5. RoleBasedPermissionEngine基于角色的权限引擎
// 职责具体的权限计算逻辑
Component
class RoleBasedPermissionEngine {private fun checkBuyerPermission(...): Boolean // BUYER角色权限private fun checkSellerPermission(...): Boolean // SELLER角色权限private fun checkAdminPermission(...): Boolean // ADMIN角色权限
}角色权限计算执行者
工作
执行具体的权限计算逻辑基于角色的权限规则资源和操作的细粒度控制数据流转过程
// 数据在各组件间的流转
HTTP请求: GET /api/v1/users/123↓
SecureController: getCurrentUserId() → 123↓
SecurityService: canAccessUser(123)↓
SecurityServiceImpl: safeCheckPermission(user, read, 123)↓
SecurityServiceImpl: getCurrentSecurityContext() → SecurityContext(userId123, roleBUYER)↓
PermissionEngine: checkPermission(context, user, read, 123)↓
RoleBasedPermissionEngine: checkBuyerPermission(context, user, read, 123)↓
SecurityContext: canAccessUserData(123) → true (同一用户)↓
返回结果: true → 允许访问为什么要这样设计
1. 单一职责原则
SecureController只负责安全基础设施SecurityService只负责业务权限接口SecurityServiceImpl只负责协调和转换PermissionEngine只负责权限计算接口RoleBasedPermissionEngine只负责具体权限逻辑
2. 开闭原则
// 可以轻松添加新的权限引擎实现
Component
class RuleBasedPermissionEngine : PermissionEngine {// 基于规则的权限计算
}Component
class DatabasePermissionEngine : PermissionEngine {// 基于数据库配置的权限计算
}3. 依赖倒置原则
// 高层模块依赖抽象不依赖具体实现
class SecurityServiceImpl(private val permissionEngine: PermissionEngine // 依赖接口不是具体实现
)4. 接口隔离原则
// 不同层次的接口职责明确
interface SecurityService { // 业务层接口fun canAccessUser(String?): Boolean
}interface PermissionEngine { // 权限计算接口fun checkPermission(...): Boolean
}总结
这5个组件形成了一个完整的权限管理体系
SecureController 安全门卫检查身份统一处理SecurityService 业务顾问提供业务语义化的权限检查SecurityServiceImpl 协调员转换格式构建上下文处理异常PermissionEngine 权限计算标准定义权限计算接口RoleBasedPermissionEngine 权限计算器执行具体的权限计算逻辑
就像一个完整的银行业务流程
门卫SecureController检查身份证业务顾问SecurityService了解业务需求业务经理SecurityServiceImpl准备材料协调各部门审批标准PermissionEngine定义审批流程审批员RoleBasedPermissionEngine根据规则做最终决定
这种设计让权限管理既灵活又可维护 ps:
好问题让我详细解释第4点和第5点的区别第4点和第5点的区别简单对比步骤组件职责具体工作第4点SecurityService权限服务调用权限引擎但不做具体判断第5点RoleBasedPermissionEngine权限引擎执行具体的权限计算逻辑 详细解析
第4点SecurityService - 权限服务中介者
// SecurityServiceImpl.kt
Service
class SecurityServiceImpl : SecurityService {override fun canAccessUser(userId: String?): Boolean {// 这里只是调用权限引擎自己不做判断return safeCheckPermission(user, read, userId)}private fun safeCheckPermission(resource: String, action: String, targetId: String?): Boolean {return try {// 1. 获取当前用户的安全上下文val context getCurrentSecurityContext() ?: return false// 2. 调用权限引擎进行检查重点这里只是调用不判断permissionEngine.checkPermission(context, resource, action, targetId)} catch (e: Exception) {false // 出错就拒绝访问}}
}SecurityService说“我收到了权限检查请求让我准备好用户信息然后交给权限引擎去判断”
SecurityService的工作转换参数将业务参数转换为权限引擎需要的格式️ 异常处理捕获异常确保系统安全 获取上下文准备当前用户的安全信息 委托调用把实际判断工作交给权限引擎
第5点RoleBasedPermissionEngine - 权限引擎实际判断者
// RoleBasedPermissionEngine.kt
class RoleBasedPermissionEngine : PermissionEngine {override fun checkPermission(context: SecurityContext, // 用户123BUYER角色resource: String, // useraction: String, // readtargetId: String? // 123): Boolean {// 这里才是真正的权限判断逻辑// 1. 非活跃用户无权限if (!context.isActive()) return false// 2. 管理员拥有所有权限if (context.isAdmin()) return true// 3. 根据角色检查权限return when (context.userRole) {Role.BUYER - checkBuyerPermission(context, resource, action, targetId)// ... 其他角色}}private fun checkBuyerPermission(context: SecurityContext,resource: String,action: String,targetId: String?): Boolean {return when (resource) {user - when (action) {read - context.canAccessUserData(targetId) // 具体的判断逻辑else - false}else - false}}
}RoleBasedPermissionEngine说“让我仔细分析…用户123是BUYER角色想读取用户123的信息这是访问自己的数据允许”
权限引擎的工作具体判断执行真正的权限计算逻辑 角色分析根据用户角色决定权限范围 资源检查判断是否可以访问特定资源⚖️ 规则执行应用具体的业务权限规则用生活例子来理解
SecurityService 银行前台接待员
客户“我想查看我的账户信息”接待员“好的让我帮您准备资料然后请权限部门审核”接待员的工作
收集客户信息准备审核材料联系权限部门处理异常情况RoleBasedPermissionEngine 银行权限审核部门
审核部门“让我看看…您是账户持有人想查看自己的账户符合规定批准”审核部门的工作
分析客户身份检查权限规则做出最终决定返回审核结果完整的调用链
// 完整的调用过程
Controller.getUserInfo(userId: 123)↓
SecurityService.canAccessUser(123) // 第4点准备和调用↓
SecurityService.safeCheckPermission(user, read, 123)↓
RoleBasedPermissionEngine.checkPermission(context, user, read, 123) // 第5点具体判断↓
RoleBasedPermissionEngine.checkBuyerPermission(...)↓
SecurityContext.canAccessUserData(123)↓
return true // 允许访问为什么要分成两层
1. 职责分离
// SecurityService业务接口层
fun canAccessUser(userId: String?): Boolean // 业务语义清晰// PermissionEngine权限计算层
fun checkPermission(context, resource, action, targetId): Boolean // 通用权限检查2. 异常处理
// SecurityService负责异常处理
private fun safeCheckPermission(...): Boolean {return try {permissionEngine.checkPermission(...) // 可能抛异常} catch (e: Exception) {false // 统一处理异常}
}3. 扩展性
// 可以轻松替换权限引擎
class SecurityServiceImpl(private val permissionEngine: PermissionEngine // 可以是不同的实现
) {// RoleBasedPermissionEngine// RuleBasedPermissionEngine // DatabasePermissionEngine
}4. 测试友好
// 可以单独测试权限引擎
Test
fun BUYER角色应该可以访问自己的数据() {val context SecurityContext(userId 123, userRole Role.BUYER)val result permissionEngine.checkPermission(context, user, read, 123)assertTrue(result)
}总结
第4点和第5点的核心区别方面SecurityService第4点RoleBasedPermissionEngine第5点角色中介者、协调者执行者、判断者职责准备数据、调用引擎、处理异常执行具体的权限计算逻辑工作“我来帮你联系权限部门”“我来判断你有没有权限”复杂度简单的转发和异常处理复杂的业务规则和权限计算可替换性相对稳定可以有多种实现基于角色、基于规则等就像餐厅点餐
SecurityService 服务员接收订单转给厨房处理问题RoleBasedPermissionEngine 厨师根据菜谱制作具体的菜品
两者配合形成了完整的权限检查流程