4、RBAC2 权限系统详细设计与实现指南(含约束与审计)

权限设计,设计模型分析(DAC,MAC,RBAC,ABAC) 之 RBAC 权限设计,设计模型分析(DAC,MAC,RBAC,ABAC) 之 RBAC:角色的权限控制 阅读详情

目录

  1. RBAC2 模型核心概念
  2. 数据库表结构设计(含约束与审计)
  3. 工作流程详解
  4. Java 实现示例(含详细中文注释)
  5. API 使用示例
  6. 约束规则实现
  7. 审计功能增强
  8. 测试用例验证

一、RBAC2 模型核心概念

1.1 什么是 RBAC2?

RBAC2(Role-Based Access Control Level 2)在 RBAC1 的基础上增加了约束机制,用于定义角色分配和权限使用的业务规则,主要包括:

  • 角色互斥(Mutual Exclusion):某些角色不能同时分配给同一个用户
  • 基数约束(Cardinality Constraints):限制角色的用户数量或用户的角色数量
  • 先决条件约束(Prerequisite Constraints):分配某角色前必须先拥有其他角色
  • 运行时约束(Runtime Constraints):动态权限检查(如时间、IP等)

1.2 核心约束类型详解

1.2.1 角色互斥约束
  • 静态互斥:用户不能同时拥有互斥角色(如会计和出纳)
  • 动态互斥:用户在同一会话中不能同时激活互斥角色
1.2.2 基数约束
  • 用户基数:限制单个用户可拥有的角色数量
  • 角色基数:限制单个角色可分配的用户数量
1.2.3 先决条件约束
  • 分配高级角色前必须先拥有基础角色
  • 例如:分配"总监"角色前必须先拥有"经理"角色

1.3 形象类比

银行内部管控:

  • 互斥约束:会计角色和出纳角色互斥,同一人不能既管账又管钱
  • 基数约束:系统管理员角色最多只能分配给3个人
  • 先决条件:要成为高级审计员,必须先担任普通审计员至少1年

这些约束确保了职责分离和风险控制,符合金融行业的合规要求

1.4 RBAC 模型演进对比

特性RBAC0RBAC1RBAC2
基础关系用户-角色-权限+角色继承+约束机制
灵活性低中高
复杂度简单中等复杂
适用场景小型应用中型企业大型企业/金融/政府

二、数据库表结构设计(含约束与审计)

2.1 表结构总览

表名说明关系
sys_user用户表-
sys_role角色表-
sys_role_hierarchy角色继承关系表父角色 ↔ 子角色
sys_permission权限表-
sys_user_role用户-角色关联表用户 ↔ 角色
sys_role_permission角色-权限关联表角色 ↔ 权限
sys_role_constraint角色约束表定义各种约束规则
sys_constraint_violation_log约束违规日志表记录约束违规尝试
sys_audit_log审计日志表记录所有权限变更

2.2 新增约束相关表结构

2.2.1 角色约束表 (sys_role_constraint) - 核心新增
CREATE TABLE `sys_role_constraint` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '约束ID',
  `constraint_type` VARCHAR(30) NOT NULL COMMENT '约束类型:MUTUAL_EXCLUSION-互斥, CARDINALITY-基数, PREREQUISITE-先决条件',
  `constraint_subtype` VARCHAR(30) DEFAULT NULL COMMENT '约束子类型:STATIC-静态, DYNAMIC-动态(互斥约束用)',
  `primary_role_id` BIGINT NOT NULL COMMENT '主角色ID(约束的主体角色)',
  `secondary_role_id` BIGINT DEFAULT NULL COMMENT '次角色ID(互斥约束的另一个角色,先决条件的前置角色)',
  `cardinality_limit` INT DEFAULT NULL COMMENT '基数限制值(基数约束用)',
  `constraint_scope` VARCHAR(20) NOT NULL COMMENT '约束范围:USER-用户级, ROLE-角色级',
  `description` VARCHAR(200) DEFAULT NULL COMMENT '约束描述',
  `status` TINYINT DEFAULT 1 COMMENT '状态:1-启用,0-禁用',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_primary_role` (`primary_role_id`),
  KEY `idx_secondary_role` (`secondary_role_id`),
  KEY `idx_constraint_type` (`constraint_type`),
  -- 互斥约束需要两个角色ID
  CONSTRAINT `chk_mutual_exclusion_roles` CHECK (
    (`constraint_type` = 'MUTUAL_EXCLUSION' AND `secondary_role_id` IS NOT NULL) OR
    (`constraint_type` != 'MUTUAL_EXCLUSION')
  ),
  -- 基数约束需要限制值
  CONSTRAINT `chk_cardinality_limit` CHECK (
    (`constraint_type` = 'CARDINALITY' AND `cardinality_limit` IS NOT NULL) OR
    (`constraint_type` != 'CARDINALITY')
  )
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色约束表';
2.2.2 约束违规日志表 (sys_constraint_violation_log) - 新增
CREATE TABLE `sys_constraint_violation_log` (
  `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '违规日志ID',
  `constraint_id` BIGINT NOT NULL COMMENT '违反的约束ID',
  `constraint_type` VARCHAR(30) NOT NULL COMMENT '约束类型',
  `user_id` BIGINT NOT NULL COMMENT '违规用户ID',
  `attempted_operation` VARCHAR(50) NOT NULL COMMENT '尝试的操作:ASSIGN_ROLE, ACTIVATE_ROLE, ACCESS_RESOURCE',
  `violation_details` JSON DEFAULT NULL COMMENT '违规详情(JSON格式)',
  `ip_address` VARCHAR(45) DEFAULT NULL COMMENT '操作IP地址',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '违规时间',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_constraint_id` (`constraint_id`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='约束违规日志表';
2.2.3 角色表增强 (sys_role)
-- 在原有角色表基础上增加约束相关字段
ALTER TABLE `sys_role` 
ADD COLUMN `max_users` INT DEFAULT NULL COMMENT '最大用户数(基数约束)',
ADD COLUMN `min_prerequisite_roles` INT DEFAULT 0 COMMENT '最少前置角色数';

2.3 示例约束数据

2.3.1 互斥约束示例
-- 会计和出纳角色互斥(静态互斥)
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_subtype, 
    primary_role_id, 
    secondary_role_id, 
    constraint_scope, 
    description
) VALUES 
('MUTUAL_EXCLUSION', 'STATIC', 4, 5, 'USER', '会计和出纳角色互斥'),
('MUTUAL_EXCLUSION', 'STATIC', 5, 4, 'USER', '出纳和会计角色互斥');

-- 系统管理员和普通用户角色互斥
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_subtype, 
    primary_role_id, 
    secondary_role_id, 
    constraint_scope, 
    description
) VALUES 
('MUTUAL_EXCLUSION', 'STATIC', 6, 7, 'USER', '管理员和普通用户互斥');
2.3.2 基数约束示例
-- 系统管理员角色最多3个用户
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_scope, 
    primary_role_id, 
    cardinality_limit, 
    description
) VALUES 
('CARDINALITY', 'ROLE', 6, 3, '系统管理员最多3人');

-- 每个用户最多拥有5个角色
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_scope, 
    primary_role_id, 
    cardinality_limit, 
    description
) VALUES 
('CARDINALITY', 'USER', 0, 5, '用户角色数量限制'); -- primary_role_id=0表示全局约束
2.3.3 先决条件约束示例
-- 分配总监角色前必须先拥有经理角色
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_scope, 
    primary_role_id, 
    secondary_role_id, 
    description
) VALUES 
('PREREQUISITE', 'USER', 3, 2, '总监角色需要先拥有经理角色');

-- 分配高级审计员前必须先拥有普通审计员
INSERT INTO sys_role_constraint (
    constraint_type, 
    constraint_scope, 
    primary_role_id, 
    secondary_role_id, 
    description
) VALUES 
('PREREQUISITE', 'USER', 8, 9, '高级审计员需要先拥有普通审计员角色');

三、RBAC2 工作流程详解

3.1 角色分配约束检查流程

管理员系统约束服务数据库分配角色给用户检查角色分配约束查询用户当前角色返回当前角色列表查询相关约束规则返回约束规则列表约束检查通过执行角色分配记录审计日志分配成功约束检查失败记录约束违规日志分配失败,返回具体约束信息alt[通过所有约束检查][违反约束规则]管理员系统约束服务数据库

3.2 权限验证约束检查流程

用户API接口权限服务约束服务请求敏感操作检查基础权限基础权限通过检查运行时约束验证动态互斥、时间、IP等约束约束检查通过执行操作成功约束检查失败返回约束违规错误alt[通过约束检查][违反约束]用户API接口权限服务约束服务

3.3 核心约束检查逻辑

3.3.1 互斥约束检查
  1. 获取用户当前所有角色
  2. 获取待分配角色的所有互斥角色
  3. 检查当前角色中是否包含互斥角色
  4. 如果包含,拒绝分配
3.3.2 基数约束检查
  • 用户基数:检查用户当前角色数量 + 新角色 ≤ 限制值
  • 角色基数:检查角色当前用户数量 + 新用户 ≤ 限制值
3.3.3 先决条件约束检查
  1. 获取待分配角色的所有先决条件角色
  2. 检查用户当前角色是否包含所有先决条件角色
  3. 如果不包含,拒绝分配

四、Java 实现示例(含详细中文注释)

4.1 约束相关实体类

角色约束实体
/**
 * 角色约束实体类
 * 对应数据库表:sys_role_constraint
 * 定义各种RBAC2约束规则
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RoleConstraint {
    /**
     * 约束ID,主键
     */
    private Long id;
    
    /**
     * 约束类型:
     * MUTUAL_EXCLUSION - 互斥约束
     * CARDINALITY - 基数约束  
     * PREREQUISITE - 先决条件约束
     */
    private String constraintType;
    
    /**
     * 约束子类型(主要用于互斥约束):
     * STATIC - 静态互斥(用户不能同时拥有)
     * DYNAMIC - 动态互斥(会话中不能同时激活)
     */
    private String constraintSubtype;
    
    /**
     * 主角色ID(约束的主体角色)
     * 例如:互斥约束中的会计角色ID
     *      基数约束中的被限制角色ID
     *      先决条件约束中的目标角色ID
     */
    private Long primaryRoleId;
    
    /**
     * 次角色ID(约束的关联角色):
     * 互斥约束:另一个互斥角色ID
     * 先决条件约束:前置角色ID
     * 基数约束:此字段为null
     */
    private Long secondaryRoleId;
    
    /**
     * 基数限制值(仅基数约束使用)
     * 例如:角色最多分配给3个用户
     *      用户最多拥有5个角色
     */
    private Integer cardinalityLimit;
    
    /**
     * 约束范围:
     * USER - 用户级约束(限制用户的行为)
     * ROLE - 角色级约束(限制角色的分配)
     */
    private String constraintScope;
    
    /**
     * 约束描述,用于显示和日志记录
     */
    private String description;
    
    /**
     * 约束状态:1-启用,0-禁用
     */
    private Integer status;
    
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}
约束违规日志实体
/**
 * 约束违规日志实体类
 * 对应数据库表:sys_constraint_violation_log
 * 记录所有违反约束规则的尝试
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ConstraintViolationLog {
    /**
     * 违规日志ID,主键
     */
    private Long id;
    
    /**
     * 违反的约束ID
     */
    private Long constraintId;
    
    /**
     * 约束类型(冗余存储,便于查询)
     */
    private String constraintType;
    
    /**
     * 违规用户ID
     */
    private Long userId;
    
    /**
     * 尝试的操作类型:
     * ASSIGN_ROLE - 分配角色
     * ACTIVATE_ROLE - 激活角色
     * ACCESS_RESOURCE - 访问资源
     */
    private String attemptedOperation;
    
    /**
     * 违规详情(JSON格式)
     * 包含违规的具体原因、相关角色、当前状态等
     */
    private String violationDetails;
    
    /**
     * 操作IP地址
     */
    private String ipAddress;
    
    /**
     * 违规时间
     */
    private LocalDateTime createTime;
}

4.2 约束服务核心实现

/**
 * RBAC2约束服务实现类
 * 负责各种约束规则的检查和验证
 */
@Service
@Slf4j
public class Rbac2ConstraintService {
    
    @Autowired
    private RoleConstraintMapper roleConstraintMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ConstraintViolationLogService violationLogService;
    
    /**
     * 检查分配角色给用户是否违反约束规则
     * 这是RBAC2的核心约束检查方法
     * 
     * 检查顺序:
     * 1. 互斥约束检查
     * 2. 基数约束检查  
     * 3. 先决条件约束检查
     * 
     * @param userId 用户ID
     * @param roleId 待分配的角色ID
     * @param operatorId 操作人ID(用于审计)
     * @param request 审计信息
     * @throws ConstraintViolationException 违反约束时抛出异常
     */
    public void checkRoleAssignmentConstraints(Long userId, Long roleId, 
                                             Long operatorId, AuditRequest request) 
            throws ConstraintViolationException {
        log.info("开始检查角色分配约束: userId={}, roleId={}", userId, roleId);
        
        try {
            // 1. 获取用户当前所有角色
            List<Long> currentUserRoleIds = userMapper.selectRoleIdsByUserId(userId);
            log.debug("用户当前角色ID列表: {}", currentUserRoleIds);
            
            // 2. 检查互斥约束
            checkMutualExclusionConstraints(userId, roleId, currentUserRoleIds, request);
            
            // 3. 检查基数约束
            checkCardinalityConstraints(userId, roleId, currentUserRoleIds, request);
            
            // 4. 检查先决条件约束
            checkPrerequisiteConstraints(userId, roleId, currentUserRoleIds, request);
            
            log.info("角色分配约束检查通过: userId={}, roleId={}", userId, roleId);
            
        } catch (ConstraintViolationException e) {
            // 记录约束违规日志
            violationLogService.logViolation(
                e.getConstraintId(),
                e.getConstraintType(),
                userId,
                "ASSIGN_ROLE",
                e.getViolationDetails(),
                request.getIpAddress()
            );
            throw e;
        } catch (Exception e) {
            log.error("约束检查发生异常", e);
            throw new ConstraintViolationException("约束检查失败", e);
        }
    }
    
    /**
     * 检查互斥约束
     * 确保用户不会同时拥有互斥角色
     * 
     * @param userId 用户ID
     * @param newRoleId 待分配的新角色ID
     * @param currentUserRoleIds 用户当前角色ID列表
     * @param request 审计请求
     * @throws ConstraintViolationException 违反互斥约束时抛出
     */
    private void checkMutualExclusionConstraints(Long userId, Long newRoleId,
                                               List<Long> currentUserRoleIds,
                                               AuditRequest request) 
            throws ConstraintViolationException {
        log.debug("开始检查互斥约束: newRoleId={}", newRoleId);
        
        // 查询新角色的所有互斥角色
        List<RoleConstraint> mutualExclusionConstraints = 
            roleConstraintMapper.selectMutualExclusionConstraints(newRoleId);
        
        if (CollectionUtils.isEmpty(mutualExclusionConstraints)) {
            log.debug("角色 {} 没有互斥约束", newRoleId);
            return;
        }
        
        // 检查用户当前角色是否包含任何互斥角色
        Set<Long> mutualExclusionRoleIds = mutualExclusionConstraints.stream()
                .map(RoleConstraint::getSecondaryRoleId)
                .collect(Collectors.toSet());
        
        for (Long currentRoleId : currentUserRoleIds) {
            if (mutualExclusionRoleIds.contains(currentRoleId)) {
                // 找到互斥角色,构建违规详情
                RoleConstraint violatedConstraint = mutualExclusionConstraints.stream()
                        .filter(c -> c.getSecondaryRoleId().equals(currentRoleId))
                        .findFirst()
                        .orElse(null);
                
                String violationDetails = buildViolationDetails(
                    "用户不能同时拥有互斥角色",
                    Map.of(
                        "userId", userId,
                        "newRoleId", newRoleId,
                        "existingRoleId", currentRoleId,
                        "constraintId", violatedConstraint != null ? violatedConstraint.getId() : null
                    )
                );
                
                log.warn("违反互斥约束: userId={}, newRoleId={}, existingRoleId={}", 
                        userId, newRoleId, currentRoleId);
                
                throw new ConstraintViolationException(
                    "角色分配违反互斥约束",
                    violatedConstraint != null ? violatedConstraint.getId() : null,
                    "MUTUAL_EXCLUSION",
                    violationDetails
                );
            }
        }
        
        log.debug("互斥约束检查通过");
    }
    
    /**
     * 检查基数约束
     * 包括用户角色数量限制和角色用户数量限制
     * 
     * @param userId 用户ID
     * @param newRoleId 待分配的新角色ID
     * @param currentUserRoleIds 用户当前角色ID列表
     * @param request 审计请求
     * @throws ConstraintViolationException 违反基数约束时抛出
     */
    private void checkCardinalityConstraints(Long userId, Long newRoleId,
                                           List<Long> currentUserRoleIds,
                                           AuditRequest request) 
            throws ConstraintViolationException {
        log.debug("开始检查基数约束");
        
        // 1. 检查用户角色数量限制(用户级基数约束)
        checkUserCardinalityConstraint(userId, newRoleId, currentUserRoleIds);
        
        // 2. 检查角色用户数量限制(角色级基数约束)
        checkRoleCardinalityConstraint(newRoleId);
        
        log.debug("基数约束检查通过");
    }
    
    /**
     * 检查用户角色数量限制
     */
    private void checkUserCardinalityConstraint(Long userId, Long newRoleId,
                                              List<Long> currentUserRoleIds) 
            throws ConstraintViolationException {
        // 查询用户级基数约束(primary_role_id = 0 表示全局用户约束)
        RoleConstraint userCardinalityConstraint = 
            roleConstraintMapper.selectUserCardinalityConstraint();
        
        if (userCardinalityConstraint == null) {
            return; // 没有用户基数约束
        }
        
        int newUserRoleCount = currentUserRoleIds.size() + 1;
        int limit = userCardinalityConstraint.getCardinalityLimit();
        
        if (newUserRoleCount > limit) {
            String violationDetails = buildViolationDetails(
                "用户角色数量超出限制",
                Map.of(
                    "userId", userId,
                    "currentRoleCount", currentUserRoleIds.size(),
                    "newRoleCount", newUserRoleCount,
                    "limit", limit,
                    "constraintId", userCardinalityConstraint.getId()
                )
            );
            
            log.warn("违反用户基数约束: userId={}, currentCount={}, newCount={}, limit={}", 
                    userId, currentUserRoleIds.size(), newUserRoleCount, limit);
            
            throw new ConstraintViolationException(
                String.format("用户最多只能拥有%d个角色", limit),
                userCardinalityConstraint.getId(),
                "CARDINALITY",
                violationDetails
            );
        }
    }
    
    /**
     * 检查角色用户数量限制
     */
    private void checkRoleCardinalityConstraint(Long roleId) 
            throws ConstraintViolationException {
        // 查询角色级基数约束
        RoleConstraint roleCardinalityConstraint = 
            roleConstraintMapper.selectRoleCardinalityConstraint(roleId);
        
        if (roleCardinalityConstraint == null) {
            return; // 没有角色基数约束
        }
        
        // 获取角色当前用户数量
        int currentUserCount = userMapper.selectUserCountByRoleId(roleId);
        int newTotalCount = currentUserCount + 1;
        int limit = roleCardinalityConstraint.getCardinalityLimit();
        
        if (newTotalCount > limit) {
            String violationDetails = buildViolationDetails(
                "角色用户数量超出限制",
                Map.of(
                    "roleId", roleId,
                    "currentUserCount", currentUserCount,
                    "newTotalCount", newTotalCount,
                    "limit", limit,
                    "constraintId", roleCardinalityConstraint.getId()
                )
            );
            
            log.warn("违反角色基数约束: roleId={}, currentCount={}, newCount={}, limit={}", 
                    roleId, currentUserCount, newTotalCount, limit);
            
            throw new ConstraintViolationException(
                String.format("角色最多只能分配给%d个用户", limit),
                roleCardinalityConstraint.getId(),
                "CARDINALITY",
                violationDetails
            );
        }
    }
    
    /**
     * 检查先决条件约束
     * 确保分配高级角色前用户已拥有必要的前置角色
     * 
     * @param userId 用户ID
     * @param newRoleId 待分配的新角色ID
     * @param currentUserRoleIds 用户当前角色ID列表
     * @param request 审计请求
     * @throws ConstraintViolationException 违反先决条件约束时抛出
     */
    private void checkPrerequisiteConstraints(Long userId, Long newRoleId,
                                            List<Long> currentUserRoleIds,
                                            AuditRequest request) 
            throws ConstraintViolationException {
        log.debug("开始检查先决条件约束: newRoleId={}", newRoleId);
        
        // 查询新角色的所有先决条件角色
        List<RoleConstraint> prerequisiteConstraints = 
            roleConstraintMapper.selectPrerequisiteConstraints(newRoleId);
        
        if (CollectionUtils.isEmpty(prerequisiteConstraints)) {
            log.debug("角色 {} 没有先决条件约束", newRoleId);
            return;
        }
        
        Set<Long> currentUserRoleSet = new HashSet<>(currentUserRoleIds);
        Set<Long> missingPrerequisites = new HashSet<>();
        
        // 检查是否缺少任何先决条件角色
        for (RoleConstraint constraint : prerequisiteConstraints) {
            Long prerequisiteRoleId = constraint.getSecondaryRoleId();
            if (!currentUserRoleSet.contains(prerequisiteRoleId)) {
                missingPrerequisites.add(prerequisiteRoleId);
            }
        }
        
        if (!missingPrerequisites.isEmpty()) {
            String violationDetails = buildViolationDetails(
                "缺少先决条件角色",
                Map.of(
                    "userId", userId,
                    "targetRoleId", newRoleId,
                    "missingPrerequisites", missingPrerequisites,
                    "currentRoles", currentUserRoleIds,
                    "constraintIds", prerequisiteConstraints.stream()
                            .map(RoleConstraint::getId)
                            .collect(Collectors.toList())
                )
            );
            
            log.warn("违反先决条件约束: userId={}, targetRoleId={}, missingPrerequisites={}", 
                    userId, newRoleId, missingPrerequisites);
            
            // 使用第一个约束的ID作为代表
            Long constraintId = prerequisiteConstraints.get(0).getId();
            
            throw new ConstraintViolationException(
                "分配角色前必须先拥有必要的前置角色",
                constraintId,
                "PREREQUISITE",
                violationDetails
            );
        }
        
        log.debug("先决条件约束检查通过");
    }
    
    /**
     * 构建违规详情JSON字符串
     */
    private String buildViolationDetails(String reason, Map<String, Object> details) {
        Map<String, Object> violationInfo = new HashMap<>();
        violationInfo.put("reason", reason);
        violationInfo.put("details", details);
        violationInfo.put("timestamp", LocalDateTime.now());
        
        try {
            return JsonUtils.toJson(violationInfo);
        } catch (Exception e) {
            log.error("构建违规详情JSON失败", e);
            return "{\"reason\":\"" + reason + "\",\"error\":\"JSON序列化失败\"}";
        }
    }
}

4.3 约束违规异常定义

/**
 * 约束违规异常
 * 用于表示违反RBAC2约束规则的情况
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ConstraintViolationException extends RuntimeException {
    
    /**
     * 违反的约束ID
     */
    private Long constraintId;
    
    /**
     * 约束类型
     */
    private String constraintType;
    
    /**
     * 违规详情
     */
    private String violationDetails;
    
    public ConstraintViolationException(String message, Long constraintId, 
                                      String constraintType, String violationDetails) {
        super(message);
        this.constraintId = constraintId;
        this.constraintType = constraintType;
        this.violationDetails = violationDetails;
    }
    
    public ConstraintViolationException(String message, Throwable cause) {
        super(message, cause);
    }
}

4.4 约束违规日志服务

/**
 * 约束违规日志服务
 * 负责记录所有违反约束规则的尝试
 */
@Service
@Slf4j
public class ConstraintViolationLogService {
    
    @Autowired
    private ConstraintViolationLogMapper violationLogMapper;
    
    /**
     * 记录约束违规日志
     * 
     * @param constraintId 约束ID
     * @param constraintType 约束类型
     * @param userId 违规用户ID
     * @param attemptedOperation 尝试的操作
     * @param violationDetails 违规详情
     * @param ipAddress 操作IP
     */
    public void logViolation(Long constraintId, String constraintType, 
                           Long userId, String attemptedOperation,
                           String violationDetails, String ipAddress) {
        try {
            ConstraintViolationLog log = ConstraintViolationLog.builder()
                    .constraintId(constraintId)
                    .constraintType(constraintType)
                    .userId(userId)
                    .attemptedOperation(attemptedOperation)
                    .violationDetails(violationDetails)
                    .ipAddress(ipAddress)
                    .build();
            
            violationLogMapper.insert(log);
            log.info("约束违规日志记录成功: userId={}, constraintType={}", userId, constraintType);
            
        } catch (Exception e) {
            log.error("记录约束违规日志失败", e);
            // 违规日志失败不应影响主业务流程
        }
    }
    
    /**
     * 查询用户的约束违规历史
     */
    public List<ConstraintViolationLog> getUserViolationHistory(Long userId) {
        return violationLogMapper.selectByUserId(userId);
    }
    
    /**
     * 查询特定约束的违规统计
     */
    public ViolationStatistics getConstraintViolationStats(Long constraintId) {
        return violationLogMapper.selectViolationStatsByConstraint(constraintId);
    }
}

五、API 使用示例

5.1 角色分配API(带约束检查)

/**
 * 角色管理Controller(支持RBAC2约束)
 */
@RestController
@RequestMapping("/api/role")
public class Rbac2RoleController {
    
    @Autowired
    private Rbac2ConstraintService constraintService;
    
    @Autowired
    private UserRoleService userRoleService;
    
    /**
     * 分配角色给用户(带RBAC2约束检查)
     * 
     * 请求示例:
     * POST /api/role/assign
     * {
     *   "userId": 1001,
     *   "roleId": 4  // 会计角色
     * }
     * 
     * 约束检查:
     * 1. 如果用户已拥有出纳角色(ID=5),则分配失败(互斥约束)
     * 2. 如果会计角色已分配给3个用户,则分配失败(基数约束)
     * 3. 如果分配总监角色但用户没有经理角色,则分配失败(先决条件)
     */
    @PostMapping("/assign")
    public Result<Void> assignRoleToUser(@RequestBody @Valid AssignRoleRequest request,
                                       HttpServletRequest httpRequest) {
        // 获取当前操作人
        Long currentUserId = getCurrentUserId(httpRequest);
        
        // 构建审计信息
        AuditRequest auditRequest = AuditRequest.builder()
                .ipAddress(getClientIpAddress(httpRequest))
                .userAgent(httpRequest.getHeader("User-Agent"))
                .build();
        
        try {
            // 1. 执行RBAC2约束检查
            constraintService.checkRoleAssignmentConstraints(
                request.getUserId(), 
                request.getRoleId(), 
                currentUserId, 
                auditRequest
            );
            
            // 2. 约束检查通过,执行角色分配
            userRoleService.assignRoleToUser(request.getUserId(), request.getRoleId());
            
            return Result.success();
            
        } catch (ConstraintViolationException e) {
            // 返回具体的约束违规信息
            log.warn("角色分配违反约束: {}", e.getMessage());
            return Result.error(ResultCode.CONSTRAINT_VIOLATION, e.getMessage())
                    .addData("constraintType", e.getConstraintType())
                    .addData("violationDetails", e.getViolationDetails());
        }
    }
    
    /**
     * 获取角色约束详情(用于前端展示)
     */
    @GetMapping("/{roleId}/constraints")
    public Result<RoleConstraintInfo> getRoleConstraints(@PathVariable Long roleId) {
        RoleConstraintInfo constraintInfo = buildRoleConstraintInfo(roleId);
        return Result.success(constraintInfo);
    }
}

5.2 约束管理API

/**
 * 约束管理Controller
 */
@RestController
@RequestMapping("/api/constraint")
public class ConstraintController {
    
    @Autowired
    private RoleConstraintService roleConstraintService;
    
    /**
     * 创建角色约束
     * 
     * 互斥约束示例:
     * POST /api/constraint
     * {
     *   "constraintType": "MUTUAL_EXCLUSION",
     *   "constraintSubtype": "STATIC",
     *   "primaryRoleId": 4,
     *   "secondaryRoleId": 5,
     *   "constraintScope": "USER",
     *   "description": "会计和出纳互斥"
     * }
     * 
     * 基数约束示例:
     * {
     *   "constraintType": "CARDINALITY",
     *   "constraintScope": "ROLE",
     *   "primaryRoleId": 6,
     *   "cardinalityLimit": 3,
     *   "description": "系统管理员最多3人"
     * }
     */
    @PostMapping
    public Result<Void> createConstraint(@RequestBody @Valid CreateConstraintRequest request) {
        roleConstraintService.createConstraint(request);
        return Result.success();
    }
    
    /**
     * 查询约束违规日志
     */
    @GetMapping("/violations")
    public Result<PageResult<ConstraintViolationLog>> getViolationLogs(
            ConstraintViolationQuery query) {
        PageResult<ConstraintViolationLog> result = 
            constraintViolationLogService.getViolationLogs(query);
        return Result.success(result);
    }
}

六、约束规则实现细节

6.1 互斥约束实现

静态互斥 vs 动态互斥
/**
 * 动态互斥约束检查(运行时检查)
 * 用于会话中角色激活的场景
 */
public boolean checkDynamicMutualExclusion(Long userId, Set<Long> activeRoleIds) {
    // 获取用户所有角色的动态互斥约束
    List<RoleConstraint> dynamicConstraints = 
        roleConstraintMapper.selectDynamicMutualExclusionConstraints(
            new ArrayList<>(activeRoleIds)
        );
    
    // 检查激活角色中是否包含互斥角色对
    Set<Long> activeRoleSet = new HashSet<>(activeRoleIds);
    for (RoleConstraint constraint : dynamicConstraints) {
        if (activeRoleSet.contains(constraint.getSecondaryRoleId())) {
            return false; // 发现互斥角色同时激活
        }
    }
    return true;
}

6.2 基数约束优化

缓存角色用户数量
/**
 * 使用Redis缓存角色用户数量,避免频繁数据库查询
 */
@Service
public class RoleCardinalityCacheService {
    
    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;
    
    private static final String ROLE_USER_COUNT_KEY = "role:user:count:%d";
    
    /**
     * 获取角色用户数量(带缓存)
     */
    public int getRoleUserCount(Long roleId) {
        String key = String.format(ROLE_USER_COUNT_KEY, roleId);
        Integer count = redisTemplate.opsForValue().get(key);
        if (count == null) {
            // 缓存未命中,查询数据库
            count = userMapper.selectUserCountByRoleId(roleId);
            redisTemplate.opsForValue().set(key, count, 5, TimeUnit.MINUTES);
        }
        return count;
    }
    
    /**
     * 更新角色用户数量缓存
     */
    public void updateRoleUserCount(Long roleId) {
        String key = String.format(ROLE_USER_COUNT_KEY, roleId);
        int newCount = userMapper.selectUserCountByRoleId(roleId);
        redisTemplate.opsForValue().set(key, newCount, 5, TimeUnit.MINUTES);
    }
}

七、审计功能增强

7.1 约束相关审计日志

约束创建审计
{
  "operationType": "CREATE",
  "targetType": "CONSTRAINT",
  "targetId": 101,
  "operationDetails": {
    "constraintType": "MUTUAL_EXCLUSION",
    "primaryRoleId": 4,
    "secondaryRoleId": 5,
    "constraintScope": "USER",
    "description": "会计和出纳互斥"
  }
}
约束违规审计
{
  "operationType": "VIOLATION",
  "targetType": "CONSTRAINT",
  "targetId": 101,
  "operationDetails": {
    "userId": 1001,
    "attemptedOperation": "ASSIGN_ROLE",
    "violationReason": "用户不能同时拥有互斥角色",
    "currentRoles": [5],
    "attemptedRole": 4
  }
}

7.2 审计查询增强

/**
 * 审计日志查询支持约束相关操作
 */
public List<AuditLog> getConstraintRelatedAuditLogs(Long constraintId) {
    return auditLogMapper.selectByCondition(AuditLogQuery.builder()
            .targetType("CONSTRAINT")
            .targetId(constraintId)
            .build());
}

八、测试用例验证

8.1 互斥约束测试

@Test
void testMutualExclusionConstraint_ShouldPreventConflictingRoleAssignment() {
    // 准备数据:
    // - 用户ID=1001 已拥有出纳角色(ID=5)
    // - 会计角色(ID=4)和出纳角色(ID=5)互斥
    
    // 尝试分配会计角色给用户
    ConstraintViolationException exception = assertThrows(
        ConstraintViolationException.class,
        () -> constraintService.checkRoleAssignmentConstraints(1001L, 4L, 1L, createAuditRequest())
    );
    
    assertEquals("MUTUAL_EXCLUSION", exception.getConstraintType());
    assertTrue(exception.getMessage().contains("互斥约束"));
    
    // 验证违规日志已记录
    List<ConstraintViolationLog> logs = violationLogService.getUserViolationHistory(1001L);
    assertEquals(1, logs.size());
    assertEquals("ASSIGN_ROLE", logs.get(0).getAttemptedOperation());
}

8.2 基数约束测试

@Test
void testCardinalityConstraint_ShouldLimitRoleAssignments() {
    // 准备数据:
    // - 系统管理员角色(ID=6)基数限制为3
    // - 当前已有3个用户拥有该角色
    
    // 尝试分配第4个用户
    ConstraintViolationException exception = assertThrows(
        ConstraintViolationException.class,
        () -> constraintService.checkRoleAssignmentConstraints(1004L, 6L, 1L, createAuditRequest())
    );
    
    assertEquals("CARDINALITY", exception.getConstraintType());
    assertTrue(exception.getMessage().contains("最多只能分配给3个用户"));
}

8.3 先决条件约束测试

@Test
void testPrerequisiteConstraint_ShouldRequireBaseRoles() {
    // 准备数据:
    // - 用户ID=1001 没有任何角色
    // - 总监角色(ID=3)需要先拥有经理角色(ID=2)
    
    // 尝试直接分配总监角色
    ConstraintViolationException exception = assertThrows(
        ConstraintViolationException.class,
        () -> constraintService.checkRoleAssignmentConstraints(1001L, 3L, 1L, createAuditRequest())
    );
    
    assertEquals("PREREQUISITE", exception.getConstraintType());
    assertTrue(exception.getMessage().contains("前置角色"));
}

8.4 约束组合测试

@Test
void testMultipleConstraints_ShouldCheckAllConstraints() {
    // 准备复杂场景:
    // - 用户已拥有出纳角色(与会计互斥)
    // - 会计角色已达基数限制
    // - 用户缺少必要的前置角色
    
    // 应该优先报告互斥约束(第一个检查的约束)
    ConstraintViolationException exception = assertThrows(
        ConstraintViolationException.class,
        () -> constraintService.checkRoleAssignmentConstraints(1001L, 4L, 1L, createAuditRequest())
    );
    
    assertEquals("MUTUAL_EXCLUSION", exception.getConstraintType());
}

总结

RBAC2 模型通过引入约束机制,为权限系统提供了更强的业务规则控制能力,特别适用于对安全性要求较高的场景。

关键特性

  1. 互斥约束:确保职责分离,防止利益冲突
  2. 基数约束:控制权限分配的规模和范围
  3. 先决条件约束:保证权限分配的逻辑合理性
  4. 完整审计:记录所有约束相关操作和违规尝试

实施建议

  1. 约束粒度:根据业务需求合理设置约束粒度,避免过度约束
  2. 性能优化:对频繁检查的约束进行缓存
  3. 用户体验:提供清晰的约束违规提示信息
  4. 监控告警:对频繁的约束违规行为设置监控告警

RBAC2 是企业级权限系统的理想选择,能够有效支撑复杂的合规要求和安全策略。

权限系统设计与RBAC实现 本文介绍了基于角色的访问控制(RBAC)系统设计与实现。首先阐述了权限系统的重要性及基本元素,包括用户、角色、权限等核心概念。然后详细解析了RBAC模型,包括其数学表示、角色继承与层级关系,以及约束条件等高级特性。在系统设计部分,提供了数据库表结构设计和权限粒度设计方案。最后展示了Python实现的RBAC系统架构,包含资源类型枚举、操作类型枚举等核心数据模型。全文以专业的技术视角,系统性地讲解了如何构建一个安全、灵活的权限管理系统。 阅读详情

相关推荐

ThinkPHP3.2搭建的RBAC后台权限系统,含完整数据库脚本与多层权限控制逻辑

基于ThinkPHP 3.2开发的即用型后台管理项目,核心实现RBAC(基于角色的访问控制)模型,支持用户、角色、权限三者解耦管理。项目自带admin.php入口,通过角色可灵活分配菜单显示权限和按钮级操作权限,所有权限逻辑集中在Application/Admin模块中。包含rbac.sql数据库初始化文件,导入后配置数据库连接即可运行;静态资源已整合layer-v3.0.1、laydate、ichartjs1.2等常用前端组件,适配PC端管理界面。公共函数放在Common目录,模板位于Tpl,语言包支持L

rock5的博客 247

RBAC简介

目录RBAC简介RBAC0RBAC1RBAC2RBAC3 RBAC简介 RBAC是Role Based Access Control的英文缩写,意思是基于角色访问控制。 RBAC实际上就是针对产品去发掘需求时所用到的Who(角色)、What(拥有什么资源)、How(有哪些操作)的方式。 在RBAC模型中,who、what、how构成了访问权限三元组,也就是“Who对What进行How的操作。 RB...

大白能的博客 2万+

RBAC(基于角色权限管理的说明)

RBAC--RBAC--RBAC--RBAC--RBAC

【设计模式】RBAC 模型详解_rbac模式(2),真香系列

RBAC模型是一种灵活的、可扩展的权限管理方式,它将权限与角色相关联,而不是直接与用户相关联。通过定义不同的角色,并为每个角色分配相应的权限,我们可以轻松地管理用户的访问权限。这种模型不仅简化了权限管理的复杂性,还提高了系统的可维护性和可扩展性。在本篇博客中,我们将深入探讨RBAC模型的基本概念、特点、优势以及实现方式。我们将了解如何定义角色、分配权限以及实现角色的继承和层次结构。同时,我们还将介绍RBAC模型在实际应用中的一些挑战和解决方案,以帮助您更好地理解和应用这一模型。

m0_61331573的博客 1520

ArduPilot移植到自定义硬件:完整指南

详解如何将ArduPilot成功移植到自定义硬件平台,涵盖环境搭建、代码配置与调试技巧。无论是初学者还是进阶开发者,都能快速掌握ArduPilot在不同硬件上的适配方法,提升开发效率。

weixin_28931449的博客 637

LM358实战:手把手教你搭建电流检测电路(附电阻选型计算)

本文详细解析了使用LM358运算放大器搭建电流检测电路的全过程,包括基础原理、采样电阻选型、放大电路设计及PCB布局技巧。通过实战案例和精确计算,帮助工程师快速掌握低成本、高精度的电流检测方案,适用于电源管理、电机控制等多种应用场景。

weixin_30872157的博客 446

RBAC 权限设计(五)

本文介绍 RBAC2 模型以及具体的实现方案。本文仅提供实现思路供大家参考,在生产实践中请根据业务场景进行具体设计。

DC1020的博客 1503

在 Linux/Debian/Ubuntu 上使用 Brasero 刻录光盘

在 Ubuntu 系统中,Brasero 是一个非常方便的光盘刻录工具。无论是创建数据光盘、音频光盘还是刻录光盘镜像文件,Brasero 都能轻松胜任。本文将介绍如何在 Ubuntu 上安装和使用 Brasero 进行光盘刻录。

I AM COMING BACK... 3542

【设计模式】RBAC 模型详解

随着软件系统的复杂性和规模的不断增长,权限管理成为了一个至关重要的问题。在大型多人协作的系统中,如何有效地管理不同用户的访问权限,确保系统的安全性和稳定性,是每一个开发者都需要面对的挑战。为了解决这一问题,业界提出了一种被广泛应用的权限管理模型——基于角色的访问控制(Role-Based Access Control,简称RBAC)。希望通过本篇博客的学习,您能够深入了解RBAC模型的核心思想和实现原理,掌握如何在实际项目中应用RBAC模型来提高系统的安全性和可维护性。

船到桥头自然直 2640

Power EM与Signal EM解决办法与原理分析

1.面对power EM,首先检查missing via,补全via,还可以加宽,加密局部power mesh,一些power IO出pin有power EM问题,可以叠加多层线和垂直方向补power形成网络降低并联电阻和提供更多电流通路解决,这种方法还可以降低ir drop。3.先进工艺有一个via ladder的方法可以解决power/signal em问题,clock cell出pin绕线或者power rail连接power stripe通过搭梯子的方式连接,原理还是分流。

m0_61544122的博客 4739

反光柱定位算法实战05:Cartographer Landmark融合定位——从原理到实战

本文介绍了CartographerLandmark融合定位方案,该方案将反光柱作为Landmark节点直接融入Cartographer后端优化框架,避免了传统双系统切换导致的位姿跳变问题。文章详细阐述了Landmark的核心原理、数据发布格式(包括ID、坐标、权重等关键字段)以及两种工作模式(建图模式和导航模式)。特别指出组合反光柱作为Landmark可提供方向参考,有效解决镜像歧义问题。该方案通过统一优化框架实现稳定定位,尤其适用于缺乏自然特征的环境,但存在ID匹配不稳定等局限性。整体而言,Cartogr

Studying…… 423

RBAC权限模型

RBAC级别:RBAC0 ~ RBAC3 RBAC0:最核心的模型,其他的级别都是建立在该级别的基础上 RBAC1:基于RBAC0模型,进行了角色的分层,也就是说角色有了上下级的区别 RBAC2:也是基于RBAC0模型的基础上,进行了角色的访问控制 静态职责分离:SSD 主要约束: 1.互斥角色:同一个用户不能授予互斥关系的角色 2.基数约束:一个用户拥有的角色是有限的 3.先决条件约...

Angela_L的博客 1853

YOLOv8安防监控实战:跌倒/闯入/徘徊实时检测(附TensorRT加速+声光报警部署代码)

精准性:针对跌倒/闯入/徘徊的行为特征优化,准确率达89.3%,误报率低于5次/天;实时性:TensorRT加速到50+FPS,报警延迟<1秒,满足安防“黄金响应时间”;低成本:无需专用AI芯片,RTX 3060或Jetson Orin就能跑,硬件成本比传统方案低60%;易部署:代码全开源,提供从模型训练到硬件联动的完整流程,2天即可搭起原型系统。如果你的安防监控还在“漏报误报”“响应慢”,建议先从跌倒检测的姿态过滤改起——用100张样本测试,再集成TensorRT加速,90%能看到明显改善。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 678

5、RBAC3 权限系统详细设计与实现指南(RBAC1+RBAC2组合 + 完整审计)

本文介绍了RBAC3模型的核心概念与实现方案。RBAC3结合了RBAC1的角色继承特性和RBAC2的约束机制,提供全面的权限控制能力。文章详细阐述了数据库表结构设计,包括用户表、角色表、权限表及其关联关系表,并特别设计了角色继承关系表和约束机制表。此外,还提供了完整的审计体系实现方案,包含审计日志表和日志详情表。该方案适用于大型企业应用、金融系统等需要精细化权限控制的场景,兼具权限管理的灵活性和安全合规性。文章最后还提供了Java实现示例和性能优化建议。

python15397的博客 1174

发那科机器人karel程序

备份和查看发那科机器人中的 Karel 程序的过程主要包括从示教器中备份程序,并通过 RoboGuide 等仿真软件查看和运行程序。步骤相对简单,但需要确保你的设备和软件已经设置好,可以通过 FTP 或直接从示教器的外部存储设备进行操作。如果你在操作过程中遇到问题,建议查阅相关的用户手册或联系发那科的技术支持,确保设备设置正确。如果你有更具体的问题或需要进一步帮助,欢迎继续提问!希望如上措施及解决方案能够帮到有需要的你。

**My Coding Family** 1600

SIMULINK开发项目实例 1000 例专栏之第907例--基于新能源与储能系统的场景实例:液流电池在微电网中的动态响应仿真

本文介绍了如何使用Simulink对液流电池在微电网中的动态响应进行建模与仿真。重点包括:1)构建液流电池模型及其特性参数设置;2)配置双向DC-DC变换器调节充放电过程;3)搭建包含分布式能源的微电网系统;4)设计基于SOC的控制器;5)通过仿真分析系统性能指标。该教程提供了完整的建模流程和MATLAB代码示例,帮助用户验证液流电池在微电网中的稳定性和适用性。

xiaoheshang_123的博客 182

3、RBAC1 权限系统详细设计与实现指南(含审计功能)

摘要 本文详细介绍了RBAC1权限模型的设计与实现方案。RBAC1在RBAC0基础上增加了角色继承功能,支持多级层次结构,有效降低权限管理复杂度。核心内容包括:1)RBAC1模型概念与角色继承规则;2)完整数据库表结构设计,新增角色继承关系表和审计日志表;3)具体实现方案,包含Java代码示例、API设计、审计功能和测试用例。系统通过角色层级自动继承权限,避免重复分配,同时通过审计日志记录所有权限变更操作,确保系统安全性。示例数据展示了员工-经理-总监三级角色的继承关系及权限分配逻辑。

python15397的博客 939

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

RBAC权限系统分析、设计与实现

最近,因为项目上需要设计实现一个权限管理模块,所以专门整理总结了RBAC的一些知识。 目前,使用最普遍的权限管理模型正是RBAC(Role-Based Access Control)模型,这篇文章也主要是介绍基于RBAC的权限管理系统,我会从RBAC是什么、如何设计RBAC两部分来介绍。 一、RBAC是什么 1、RBAC模型概述 RBAC模型(Role-Based Access Contr...

lvshuocool的博客 2万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

基于RBAC实现权限系统

RBAC 是 Role-Based Access Control(基于角色的访问控制)的缩写。它是一种访问控制模型,用于管理和控制系统中的用户访问权限。在 RBAC 模型中,访问权限是通过角色来授权的。每个角色被分配给一个或多个用户,而每个角色具有特定的权限和访问级别。通过将权限与角色相关联,可以简化权限管理,并在需要时轻松地对用户的权限进行更改。RBAC 的核心思想是将权限的授权从用户直接关联到角色,从而提高系统的安全性和管理灵活性。

郝老三~~~~~~~~~~~~~ 2805

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

RBAC 权限模型演进解析:从RBAC0到RBAC3的4种模型对比与选型指南

本文深入解析RBAC权限模型的演进历程,对比RBAC0到RBAC3四种核心模型的特性,包括用户角色分配、权限管理和模型设计等关键要素。通过详细的技术实现方案和业务场景分析,帮助开发者根据企业需求选择合适的权限模型,提升系统的安全性和灵活性。

过客阵营 -- 简单的就要最简单 816

手撸一套RBAC权限系统

RBAC模型(Role-Based Access Control:基于角色的访问控制)模型是20世纪90年代研究出来的一种新模型,但其实在20世纪70年代的多用户计算时期,这种思想就已经被提出来,直到20世纪90年代中后期,RBAC才在研究团体中得到一些重视,并先后提出了许多类型的RBAC模型。其中以美国George Mason大学信息安全技术实验室(LIST)提出的RBAC96模型最具有代表,并得到了普遍的公认。

学无止境 1274

【工作中问题解决实践 三】深入理解RBAC权限模型

工作时遇到了需要设计一套权限系统,所以做了一些调研。目前业界比较通用的权限系统设计都是采用RBAC模型,那么我们详细理解下RBAC模型的概念以及一些实际使用中建议的使用规范: RBAC权限模型 首先了解下RBAC权限模型的基本概念和几种模型分类。 1 RBAC权限模型 RBAC(Role-Based Access Control)即:基于角色的权限控制。通过角色关联用户,角色关联权限的方式间接赋予用户权限,增加权限设置的扩展性。 为什么要有角色的概念:对于批量的用户权限调整,只需调整用户关联的角色权限,无

MaoLin Tian's Blog 2462

1、Java 后端权限系统深度指南:从理论到实战

权限系统设计与安全实践指南 本文系统介绍了权限控制的核心概念、主流模型及安全架构设计。从基础ACL到动态ABAC模型,详细解析了RBAC角色继承和约束机制。通过分层架构示例展示权限拦截器、服务接口和存储策略的实现,强调最小权限原则和防御纵深体系。包含敏感操作二次验证、权限缓存安全等实战技巧,并给出Spring Security代码示例和审计日志方案。最后总结多场景技术选型建议,帮助开发者构建安全高效的权限系统。

python15397的博客 1178

【安全建设】深入解析基于角色的访问控制(RBAC)模型

基于角色的访问控制(Role-Based Access Control,简称RBAC)是一种广泛应用于信息系统权限管理的模型。其核心思想是通过角色这一中间层来间接赋予用户权限,从而简化权限管理流程。RBAC模型将权限控制抽象为一个逻辑判断过程:确定"谁(Who)可以对什么资源(What)进行何种操作(How)",并验证该逻辑表达式是否为真。这个三元组构成了权限管理的基础框架。

KP_0x01的博客 1820
上一篇: 3、RBAC1 权限系统详细设计与实现指南(含审计功能)
下一篇: 5、RBAC3 权限系统详细设计与实现指南(RBAC1+RBAC2组合 + 完整审计)
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值