yudao-cloud访问控制:基于属性的访问控制模型
概述
在现代企业级应用开发中,访问控制是确保系统安全的核心机制。yudao-cloud作为一款功能强大的后台管理系统,采用了基于属性的访问控制(Attribute-Based Access Control,ABAC)模型,为开发者提供了灵活、细粒度的权限管理能力。
ABAC模型通过评估主体(用户)、资源(数据)、操作(动作)和环境(上下文)的属性来决定访问权限,相比传统的基于角色的访问控制(RBAC)更加灵活和强大。
yudao-cloud ABAC架构设计
核心组件架构
核心接口定义
yudao-cloud通过SecurityFrameworkService接口定义了权限校验的核心操作:
public interface SecurityFrameworkService {
boolean hasPermission(String permission);
boolean hasAnyPermissions(String... permissions);
boolean hasRole(String role);
boolean hasAnyRoles(String... roles);
boolean hasScope(String scope);
boolean hasAnyScopes(String... scope);
}
属性定义与分类
1. 用户属性(Subject Attributes)
public class LoginUser {
private Long id; // 用户ID
private String username; // 用户名
private Integer userType; // 用户类型
private Long deptId; // 部门ID
private Long tenantId; // 租户ID
private List<Long> roleIds; // 角色ID列表
private List<String> permissions; // 权限列表
private List<String> scopes; // 授权范围
private Map<String, Object> context;// 上下文属性
// 支持动态属性扩展
public void setContext(String key, Object value) {
context.put(key, value);
}
public <T> T getContext(String key, Class<T> type) {
return type.cast(context.get(key));
}
}
2. 资源属性(Resource Attributes)
| 属性类型 | 示例值 | 描述 |
|---|---|---|
| 资源ID | user:read | 资源唯一标识符 |
| 资源类型 | DATA, API, MENU | 资源分类 |
| 敏感级别 | PUBLIC, INTERNAL, CONFIDENTIAL | 数据敏感度 |
| 所属租户 | tenant_001 | 多租户隔离 |
3. 环境属性(Environment Attributes)
| 属性类型 | 示例 | 描述 |
|---|---|---|
| 时间 | 09:00-18:00 | 访问时间限制 |
| 位置 | 192.168.1.0/24 | IP地址范围 |
| 设备类型 | DESKTOP, MOBILE | 客户端设备 |
权限策略引擎实现
策略执行流程
缓存优化机制
yudao-cloud采用多级缓存策略提升性能:
// 权限缓存配置
private final LoadingCache<KeyValue<Long, List<String>>, Boolean> hasAnyPermissionsCache = buildCache(
Duration.ofMinutes(1L), // 1分钟过期
new CacheLoader<KeyValue<Long, List<String>>, Boolean>() {
@Override
public Boolean load(KeyValue<Long, List<String>> key) {
return permissionApi.hasAnyPermissions(
key.getKey(),
key.getValue().toArray(new String[0])
).getCheckedData();
}
});
实际应用场景
场景1:多租户数据隔离
@PreAuthorize("@ss.hasPermission('system:user:query')")
public CommonResult<PageResult<UserVO>> getUserPage(UserPageReqVO reqVO) {
// 自动注入租户ID属性
Long tenantId = SecurityFrameworkUtils.getLoginUser().getTenantId();
reqVO.setTenantId(tenantId);
return success(userService.getUserPage(reqVO));
}
场景2:动态权限控制
// 基于部门和角色的复合权限控制
@PreAuthorize("@ss.hasPermission('crm:customer:view') && " +
"@ss.hasRole('sales_manager') || " +
"T(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils)" +
".getLoginUser().getDeptId() == #deptId")
public CommonResult<CustomerVO> getCustomerDetail(Long customerId, Long deptId) {
// 业务逻辑
}
场景3:时间敏感操作
// 工作时间限制访问
@PreAuthorize("@ss.hasPermission('finance:transfer') && " +
"T(java.time.LocalTime).now().isAfter(T(java.time.LocalTime).of(9, 0)) && " +
"T(java.time.LocalTime).now().isBefore(T(java.time.LocalTime).of(17, 0))")
public CommonResult<Boolean> transferFunds(TransferReqVO reqVO) {
// 转账业务逻辑
}
扩展性与自定义
自定义属性解析器
@Component
public class CustomAttributeResolver {
@Autowired
private SecurityFrameworkService securityService;
public boolean evaluateCustomPolicy(String resource, String action) {
LoginUser user = SecurityFrameworkUtils.getLoginUser();
// 自定义属性评估逻辑
boolean timeValid = LocalTime.now().isAfter(LocalTime.of(8, 0));
boolean locationValid = "192.168.1.100".equals(user.getContext("ip_address"));
boolean departmentValid = user.getDeptId().equals(101L);
return timeValid && locationValid && departmentValid &&
securityService.hasPermission(resource + ":" + action);
}
}
策略配置文件示例
yudao:
security:
policies:
- name: "工作时间访问策略"
description: "仅在工作时间允许访问敏感操作"
condition: "time >= '09:00' AND time <= '18:00'"
actions: ["sensitive:operation"]
- name: "部门数据隔离策略"
description: "用户只能访问本部门数据"
condition: "user.deptId == resource.deptId"
resources: ["department:data"]
最佳实践
1. 权限设计原则
| 原则 | 说明 | 示例 |
|---|---|---|
| 最小权限 | 只授予必要权限 | user:read 而非 user:* |
| 职责分离 | 不同角色不同权限 | 管理员 vs 普通用户 |
| 定期审计 | 定期检查权限分配 | 季度权限审查 |
2. 性能优化建议
- 缓存策略:合理设置缓存过期时间,平衡实时性和性能
- 批量查询:使用
hasAnyPermissions替代多次hasPermission调用 - 异步校验:非关键权限可异步验证
3. 安全注意事项
// 避免权限绕过漏洞
@PreAuthorize("@ss.hasPermission('system:user:delete')")
public CommonResult<Boolean> deleteUser(@NotNull Long userId) {
// 必须再次验证业务逻辑权限
if (!userService.canDeleteUser(userId,
SecurityFrameworkUtils.getLoginUserId())) {
throw new ServiceException("无权删除该用户");
}
return success(userService.deleteUser(userId));
}
总结
yudao-cloud的基于属性访问控制模型提供了强大而灵活的权限管理能力。通过结合用户属性、资源属性、操作属性和环境属性,开发者可以实现细粒度的访问控制策略。该模型支持多租户隔离、动态权限控制、时间敏感操作等复杂场景,同时通过缓存优化和扩展机制确保了系统的高性能和可维护性。
在实际应用中,建议遵循最小权限原则,定期审计权限分配,并结合业务需求设计合理的属性策略,从而构建安全可靠的企业级应用系统。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



