一、先定原则:三级权限不是"三个账号",而是三层控制
工控场景的三级划分比较收敛:操作员仅监控、启停,无修改权;工程师可参数修改、配方编辑,无系统配置权;管理员拥有全权限及用户管理。
但要提醒一点:角色分级 ≠ 权限分级。真正落地时权限粒度至少要分三层——模块权限(菜单级)、功能权限(按钮级)、数据权限(范围级),数据权限还需从创建者、组织、业务维度做隔离。也就是说,同样是"工程师",A 工程师能不能看 B 产线的配方,这是数据级问题,光靠角色表解决不了。
二、数据模型设计
标准 RBAC 五张表:用户表(users)、角色表(roles)、权限表(permissions)、用户角色关联表(user_roles)、角色权限关联表(role_permissions);角色可支持继承机制,子角色自动继承父角色权限,通过 parent_id 字段或递归查询实现。
工控侧的实体可以简化,但权限一定要用编码而不是名称:权限实体绑定功能编码(如 ParamEdit、PlcDownload、UserManage),工控场景用编码更稳定;角色预设三类批量分配权限,用户绑定角色,登录验证后加载权限。
密码存储别偷懒:敏感字段如密码必须采用强哈希算法(如 PBKDF2 或 bcrypt.net)加盐存储,严禁明文或弱加密。
三、校验实现:前端防君子,后端防小人
这是最容易出问题的地方。常见错误是只在界面层做了控制,方法内部没校验,等于没做。
推荐双重控制:控件显隐/禁用 + 功能方法拦截。具体到代码层面,主窗体加载时动态构建 MenuStrip 或 ToolStrip,依据当前用户权限集合过滤菜单项;按钮 Click 事件中调用 PermissionService.HasPermission(“User_Delete”) 做运行时鉴权;关键业务方法(如删除用户)内部再嵌套一次权限校验,失败则抛出自定义 InsufficientPermissionException 并给出友好提示。
有个开源项目的做法值得参考:按钮级别的显示隐藏 + 服务层二次校验,前端防君子,后端防小人。
另外有个容易忽略的保护项:默认保留"操作员"和"管理员"角色,禁止删除,仅允许修改其权限,避免误操作导致系统无法登录。
四、操作日志:字段设计比实现更重要
日志的核心价值在于事后能还原现场。建议字段:时间、用户、操作类型、操作对象、操作内容(具体值)、结果(成功/失败)、IP 地址。关键一点:修改类操作必须记录变更前后的值。
更完整的表结构可以扩展为:记录操作人 ID、操作类型、目标资源、操作时间、IP 地址、客户端主机名、请求参数摘要、执行结果状态码及异常堆栈信息。
存储与保留策略:存储位置用数据库便于查询,保留时长建议至少 1 年,超期自动清理,并配合定期导出归档。合规口径上,重要设备、平台、系统访问和操作日志留存时间不少于 6 个月,并需定期离线备份防止篡改——实际项目建议取两者中更严的那个。
五、案例分析
案例 1:多角色共用一台上位机的权限冲突
这是产线上很真实的矛盾:操作员要一直登录着看生产,但工艺员临时来改个参数,怎么办?
比较稳妥的两种方案:一是弹窗二次身份校验——操作员保持前台生产登录不退出,生产数据绑定操作员 ID;工艺员或管理员通过独立弹窗做身份校验,通过后临时开放参数编辑权限,操作日志记录实际执行人,生产数据仍归属当班操作员,参数保存后权限自动回收。二是系统级双会话+权限委派——上位机分前台生产会话(操作员独占)与后台管理会话(独立子进程),子进程与主进程共享数据库及生产工单上下文,工艺修改操作单独写入操作人日志。
这里的关键设计点是**"操作人"和"数据归属人"要分成两个字段**,否则审计时会出现"参数是工艺员改的,但记录显示是操作员"的扯皮。
案例 2:设备状态参与权限判定
纯静态 RBAC 在设备异常时会失效。半导体行业的做法是把设备状态纳入校验:按"岗位-技能-设备"三维度设置权限矩阵,操作员仅能执行启动、停机等基础操作,工程师可调整工艺参数,维护人员仅能在设备待机时检修,管理人员有审计权限但不能直接操作设备;动态适配机制结合设备状态实时校验操作合法性——设备故障时临时向维护人员开放诊断权限,故障排除后自动回收;若操作人员试图在设备运行中调整关键参数,系统立即弹出预警并锁定操作界面,同时同步至管理人员终端。
审计侧要求也相应提高:全维度记录"操作人-时间-内容-环境-设备"五大要素,所有信息带时间戳和唯一标识确保不可篡改;权限申请、调整、回收必须留存申请人、审批人、执行人记录。
案例 3:SQLite 单机场景的加固思路
如果项目是单机部署、不想上数据库服务器,要注意 SQLite 原生不支持用户认证与 ACL,权限管理完全依赖应用层实现。可选的加固路径:为每个功能按钮分配 2^n 权限值,登录时预加载权限集合至内存,通过逻辑"与"运算动态控制 MenuStrip、ToolStrip 及控件的 Visible/Enabled/ReadOnly 属性,关键操作事件需二次校验;数据层可选用 SQLCipher 实现 AES-256 透明加密,配合 PRAGMA secure_delete=ON 防止数据恢复;审计侧用独立日志表记录敏感操作(时间戳、操作者、SQL 哈希、影响行数),并支持定时自动备份与一键恢复。
六、几个容易踩的坑
- 事务一致性。新建用户 + 分配角色 + 写入日志这类跨表操作,要用 TransactionScope 或显式 BeginTransaction 保障 ACID,否则容易出现"用户建了但角色没绑上"的脏数据。
- 权限变更本身也要留痕。设计时应遵循最小权限与职责分离原则,并记录权限变更日志以供审计。
- 别把"能看"和"能点"混为一谈。权限控制点至少要覆盖:菜单可见性(没权限就不显示)、按钮可用性(能看不能点)、数据可见范围、参数修改权限。
- 日志只增不改。这是审计的底线要求——日志不能改、不能删,且必须存够年限。
如果你说明一下是单机还是多机联网、有没有合规审计要求(GMP/IATF 之类),我可以把表结构和日志字段再具体收敛一版。