C++怎么实现一个访问控制列表(ACL)

来源:Vuejs社区作者:美谷头衔:网络博主
导读:本期聚焦于小伙伴创作的《C++怎么实现一个访问控制列表(ACL)》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++怎么实现一个访问控制列表(ACL)》有用,将其分享出去将是对创作者最好的鼓励。

访问控制列表(ACL)是一种基于规则的权限管控机制,通过维护主体对资源的操作权限列表,实现对系统资源的细粒度访问控制,在C++系统开发中,我们可以通过面向对象的方式实现一套轻量可用的ACL组件。

ACL核心概念建模

实现ACL前需要先明确核心实体的抽象,通常包含三个部分:权限主体(用户或角色)、资源对象、权限规则。我们可以用结构体分别定义这些实体:

#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <set>

// 权限类型枚举,可根据实际需求扩展
enum class Permission {
    READ = 1 << 0,   // 读权限
    WRITE = 1 << 1,  // 写权限
    EXECUTE = 1 << 2,// 执行权限
    DELETE = 1 << 3  // 删除权限
};

// 权限主体结构,支持用户和角色两种类型
struct Principal {
    std::string id;          // 主体唯一标识
    bool is_role;            // 是否为角色类型
    Principal(std::string pid, bool role) : id(pid), is_role(role) {}
    // 重载相等运算符,用于哈希表键值比较
    bool operator==(const Principal& other) const {
        return id == other.id && is_role == other.is_role;
    }
};

// 自定义Principal哈希函数,用于unordered_map存储
struct PrincipalHash {
    std::size_t operator()(const Principal& p) const {
        return std::hash<std::string>()(p.id) ^ (std::hash<bool>()(p.is_role) << 1);
    }
};

// 资源结构,标识被访问的资源
struct Resource {
    std::string id;          // 资源唯一标识
    std::string type;        // 资源类型,比如文件、接口等
    Resource(std::string rid, std::string rtype) : id(rid), type(rtype) {}
};

ACL核心管理类实现

接下来实现ACL的核心管理类,负责权限规则的增删改查和权限校验逻辑:

class AccessControlList {
private:
    // 存储结构:key为资源,value为主体到权限集合的映射
    std::unordered_map<std::string, std::unordered_map<Principal, std::set<Permission>, PrincipalHash>> acl_rules;

public:
    // 添加权限规则:给指定主体授予对指定资源的某个权限
    void add_permission(const Principal& principal, const Resource& resource, Permission perm) {
        acl_rules[resource.id][principal].insert(perm);
    }

    // 移除指定主体对指定资源的某个权限
    void remove_permission(const Principal& principal, const Resource& resource, Permission perm) {
        auto res_it = acl_rules.find(resource.id);
        if (res_it != acl_rules.end()) {
            auto prin_it = res_it->second.find(principal);
            if (prin_it != res_it->second.end()) {
                prin_it->second.erase(perm);
                // 如果主体对应权限为空,移除该主体条目
                if (prin_it->second.empty()) {
                    res_it->second.erase(principal);
                }
                // 如果资源对应所有主体权限为空,移除该资源条目
                if (res_it->second.empty()) {
                    acl_rules.erase(resource.id);
                }
            }
        }
    }

    // 校验指定主体是否有指定资源的目标权限
    bool check_permission(const Principal& principal, const Resource& resource, Permission target_perm) {
        auto res_it = acl_rules.find(resource.id);
        if (res_it == acl_rules.end()) {
            return false; // 没有该资源的任何权限规则
        }
        auto prin_it = res_it->second.find(principal);
        if (prin_it == res_it->second.end()) {
            return false; // 该主体没有该资源的任何权限
        }
        // 校验权限是否存在
        return prin_it->second.find(target_perm) != prin_it->second.end();
    }

    // 获取指定主体对指定资源的所有权限
    std::set<Permission> get_permissions(const Principal& principal, const Resource& resource) {
        auto res_it = acl_rules.find(resource.id);
        if (res_it != acl_rules.end()) {
            auto prin_it = res_it->second.find(principal);
            if (prin_it != res_it->second.end()) {
                return prin_it->second;
            }
        }
        return {};
    }
};

功能测试示例

我们可以通过以下测试代码验证ACL实现的正确性:

int main() {
    AccessControlList acl;

    // 定义主体:用户user1,角色admin
    Principal user1("user1", false);
    Principal admin_role("admin", true);

    // 定义资源:文件file1,接口api1
    Resource file1("file1", "file");
    Resource api1("api1", "api");

    // 给用户user1授予file1的读权限
    acl.add_permission(user1, file1, Permission::READ);
    // 给admin角色授予file1的读写执行权限
    acl.add_permission(admin_role, file1, Permission::READ);
    acl.add_permission(admin_role, file1, Permission::WRITE);
    acl.add_permission(admin_role, file1, Permission::EXECUTE);
    // 给admin角色授予api1的所有权限
    acl.add_permission(admin_role, api1, Permission::READ);
    acl.add_permission(admin_role, api1, Permission::WRITE);
    acl.add_permission(admin_role, api1, Permission::EXECUTE);
    acl.add_permission(admin_role, api1, Permission::DELETE);

    // 校验权限
    std::cout << "user1是否有file1读权限:" << (acl.check_permission(user1, file1, Permission::READ) ? "是" : "否") << std::endl;
    std::cout << "user1是否有file1写权限:" << (acl.check_permission(user1, file1, Permission::WRITE) ? "是" : "否") << std::endl;
    std::cout << "admin角色是否有file1执行权限:" << (acl.check_permission(admin_role, file1, Permission::EXECUTE) ? "是" : "否") << std::endl;
    std::cout << "admin角色是否有api1删除权限:" << (acl.check_permission(admin_role, api1, Permission::DELETE) ? "是" : "否") << std::endl;

    // 移除admin角色对file1的写权限
    acl.remove_permission(admin_role, file1, Permission::WRITE);
    std::cout << "移除后admin角色是否有file1写权限:" << (acl.check_permission(admin_role, file1, Permission::WRITE) ? "是" : "否") << std::endl;

    return 0;
}

实现优化方向

上述实现是基础版本,实际使用中可以根据需求扩展优化:

  • 支持权限继承:比如角色权限可以继承给用户,减少重复配置
  • 支持权限组:将多个权限打包为权限组,方便批量授予
  • 增加默认权限规则:当没有匹配的规则时,使用默认允许或默认拒绝策略
  • 加入资源层级匹配:支持通配符匹配资源标识,比如给某个目录下的所有文件统一配置权限
  • 增加权限过期机制:支持临时权限配置,到时间自动失效

整个实现过程不需要依赖第三方库,仅使用C++标准库就可以完成,开发者可以根据自身系统的权限管控需求调整实体定义和规则逻辑,快速适配不同的业务场景。

C++访问控制列表权限管理系统安全修改时间:2026-06-13 01:24:53

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。