尧图精选

权限系统是上位机从“个人工具”走向“生产系统”的分水岭

🕒 发布时间:2026/10/1 18:34:40 📁 来源:尧图网络
权限系统是上位机从“个人工具”走向“生产系统”的分水岭。它要解决两个问题谁能做什么权限控制以及谁做了什么审计追溯。工控场景的权限设计有明确的行业惯例三级用户权限和操作日志是标配。️ 权限模型用户 → 角色 → 权限三层架构工控上位机最成熟的做法是RBAC基于角色的访问控制核心思路是用户不直接绑定权限而是通过“角色”中转。用户User→ 角色Role→ 权限Permission为什么必须这样设计如果你给每个用户单独分配权限10 个用户要配 10 次。用角色中转后只需要给“操作员”角色配一次权限新来的操作员直接分配角色即可。人员流动时改角色即可不用逐个调整。 三级用户权限的工控标准划分工控上位机的三级划分有明确的行业共识直接照搬即可级别角色权限范围典型操作L1操作员仅监控、启停查看实时数据、启动/停止设备、确认报警L2工程师参数修改、配方管理修改工艺参数、编辑配方、下载程序L3管理员全权限 用户管理系统配置、用户增删、权限分配关键约束角色不可删除操作员、工程师、管理员三个默认角色必须保留仅可修改权限防止误删导致无人能登录。工程师无用户管理权工程师能改参数但不能增删用户。这是职责分离的基本原则。操作员无修改权只读不写避免误操作。权限的粒度权限应该绑定到具体操作而不是笼统的“模块”。比如“参数修改”和“参数查看”是两个不同的权限项。一个工程师可能有“参数修改”权限但操作员只有“参数查看”权限。 权限验证两道防线第一道控件显隐/禁用最常用登录后根据当前用户的权限集遍历所有菜单、按钮、工具栏把无权限的控件隐藏或禁用。这是用户能感知到的“权限”。// 登录成功后初始化权限publicvoidInitPermission(){varpermsAuthManager.CurrentUser.Permissions;// 菜单控制menuUserManage.Visibleperms.Contains(User.Manage);menuRecipe.Visibleperms.Contains(Recipe.Edit);menuAlarmClear.Visibleperms.Contains(Alarm.Clear);// 按钮控制btnWritePlc.Enabledperms.Contains(Plc.Write);btnDownload.Enabledperms.Contains(Program.Download);}第二道功能方法拦截防绕过控件隐藏只防君子不防小人。如果用户知道快捷键或者通过其他途径触发了被隐藏的方法控件层的控制就失效了。所有敏感操作的方法内部必须再做一次权限校验publicvoidWritePlcParameter(stringaddress,floatvalue){// 无论 UI 层是否拦截这里必须再检查AuthManager.EnsurePermission(Plc.Write);// 执行写入...}// AuthManager 中的校验方法publicstaticvoidEnsurePermission(stringpermission){if(!CurrentUser.Permissions.Contains(permission))thrownewUnauthorizedAccessException($无权限{permission});}工控避坑永远不要只靠 UI 隐藏来保护关键操作。写 PLC、下载程序、清除报警这些操作方法内部必须有独立的权限校验。 数据模型设计轻量方案单机上位机用 JSON/XML 文件存储用户和权限配置无需数据库。适合单机运行的场景读写简单部署零依赖。专业方案多机联网用 SQLite 或 SQL Server支持多客户端权限同步。推荐四张核心表-- 用户表CREATETABLEUsers(UserIdINTPRIMARYKEY,UserName NVARCHAR(50)UNIQUENOTNULL,PasswordHash NVARCHAR(128)NOTNULL,-- 加密存储RoleIdINTNOTNULL);-- 角色表CREATETABLERoles(RoleIdINTPRIMARYKEY,RoleName NVARCHAR(50)NOTNULL);-- 权限表CREATETABLEPermissions(PermissionIdINTPRIMARYKEY,PermissionCode NVARCHAR(100)UNIQUENOTNULL,-- 如 Plc.WriteDescription NVARCHAR(200));-- 角色-权限关联表CREATETABLERolePermissions(RoleIdINTNOTNULL,PermissionIdINTNOTNULL,PRIMARYKEY(RoleId,PermissionId)); 操作日志可追溯性的核心操作日志不是“出错才记”而是关键操作必须记。工控场景中以下操作必须记录日志日志类型记录内容典型场景登录/登出时间、用户名、IP、成功/失败安全审计参数修改时间、用户、参数名、旧值→新值工艺追溯权限变更时间、操作人、目标用户、变更内容权限审计报警确认时间、用户、报警名、确认动作责任追溯程序下载时间、用户、目标设备、程序版本变更管理日志表设计参考工业审计接口规范CREATETABLEOperationLogs(LogIdBIGINTIDENTITY(1,1)PRIMARYKEY,ActionTime DATETIME2(3)NOTNULL,-- 精确到毫秒UserIdINTNOTNULL,UserName NVARCHAR(50)NOTNULL,Module NVARCHAR(50),-- 模块编码ActionNVARCHAR(100),-- 操作类型TargetObject NVARCHAR(100),-- 操作目标OldValue NVARCHAR(MAX),-- 原值修改类操作NewValue NVARCHAR(MAX),-- 新值Result NVARCHAR(20),-- 成功/失败Details NVARCHAR(MAX)-- 扩展信息JSON);日志记录的最佳实践采用AOP面向切面编程思想把日志逻辑从业务代码中剥离。业务方法只关注业务日志通过拦截器或注解自动记录。如果不想引入 AOP 框架至少要把日志写入封装成一个独立方法在关键操作前后调用publicvoidModifyTemperatureSetpoint(floatnewValue){floatoldValue_currentSetpoint;// 记录旧值// 业务操作_plc.Write(DB1.DBD0,newValue);_currentSetpointnewValue;// 记录日志关键操作必须记LogService.Write(newOperationLog{UserNameAuthManager.CurrentUser.UserName,Module参数配置,Action修改温度设定值,TargetObjectDB1.DBD0,OldValueoldValue.ToString(),NewValuenewValue.ToString(),Result成功});}旧值→新值是日志中最有价值的信息。只记录“某某修改了参数”没有意义必须记录“从多少改成了多少”才能追溯工艺变更的全貌。⚡ 工控场景的额外优化自动登出工控机长时间无人操作时定时自动登出避免权限泄露。可以设置 10 分钟无操作自动锁定需要重新输入密码才能恢复操作。密码加密绝对不存明文。用 SHA256 或 BCrypt 加密存储。登录失败锁定连续多次密码错误后锁定账号一段时间防止暴力破解。日志定期归档操作日志会持续增长设置保留期限如 6 个月过期日志自动归档到独立文件或清理。 核心思维提炼1. 权限是“角色”的不是“人”的给“张三”配权限是错误思维给“操作员”配权限才是正确思维。张三离职换李四当操作员权限自动继承。2. 两道防线缺一不可UI 层隐藏控件是为了用户体验不显示无权限的按钮方法层校验是为了安全防止绕过 UI 调用。只做前者是“防君子”只做后者是“用户不知道不能点”。3. 日志的“新旧值”比“操作记录”重要“张三修改了温度参数”是无效信息。“张三把温度参数从 85 改为 92”才能追溯工艺变更。关键操作必须记录变更前后的值。4. 权限和日志是“一体两面”权限控制“能不能做”日志记录“做了什么”。没有权限控制的日志是无意义的没有日志的权限控制是无法追溯的。两者必须同时设计、同时实现。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →