HMI 安全
Darra HMI 提供多层安全机制,覆盖用户认证、角色权限、屏幕锁定、审计日志、电子签名五个维度。WebHMI 默认启用认证,LocalHMI 可根据部署环境配置。
本文档聚焦 HMI 运行时的安全机制。PLC 级别的安全功能(如安全块、急停、双通道冗余)见 PLC 安全总览。
用户认证 (RBAC)
认证架构
用户登录 (HMI 页面)
│
▼
HmiAuthProvider (Service 端)
│
├── 密码验证 (bcrypt, 本地用户库)
├── LDAP/AD 验证 (企业域集成)
└── 双因素认证 (TOTP / U 盾) ← 可选
│
▼
JWT Token (HttpOnly Cookie, 30 天)
│
▼
HMI 页面请求 → 验证 Token → 授权访问
启用登录
在 HMIProjectDef 中启用:
{
"RequireAuth": true,
"AuthSettings": {
"SessionTimeout": 480,
"MaxLoginAttempts": 5,
"LockoutDuration": 15,
"MfaRequired": false,
"PasswordMinLength": 8,
"PasswordComplexity": "medium",
"LdapServer": "",
"LdapDomain": ""
}
}
| 参数 | 默认值 | 说明 |
|---|---|---|
SessionTimeout | 480 | 会话超时(分钟),超时后自动登出 |
MaxLoginAttempts | 5 | 连续登录失败次数上限 |
LockoutDuration | 15 | 锁定时间(分钟) |
MfaRequired | false | 是否强制双因素认证 |
PasswordMinLength | 8 | 密码最小长度 |
PasswordComplexity | medium | 密码复杂度:low / medium / high |
登录页面
HMI 自动提供登录页面(/login),使用 <darra-login-panel> 控件:
<darra-login-panel redirect-on-success="/"></darra-login-panel>
登录成功写入 Cookie darra-token(HttpOnly、Secure、SameSite=Strict),后续请求自动认证。
登录 API(脚本)
// 检查当前是否已登录
const isAuth = Darra.checkAuth()
// true | false
// 获取当前用户信息
const user = Darra.getUserInfo()
// { username: 'wang', role: 'engineer', displayName: '王工', permissions: [...] }
// 登出
Darra.logout()
角色与权限 (RBAC)
预定义角色
| 角色 | 权限范围 | 典型用户 |
|---|---|---|
viewer | 只读,查看变量、报警、趋势 | 参观者、质量巡检 |
operator | 读写操作变量、确认报警、切换配方 | 产线操作员 |
engineer | 修改配方、调整参数、更改 HMI 页面 | 工艺工程师 |
admin | 所有权限,包括用户管理、审计查看 | 车间主管、IT |
权限门控控件
<!-- 仅 admin 可见 -->
<darra-permission-gate role="admin">
<darra-button var="M100.0">紧急停车</darra-button>
</darra-permission-gate>
<!-- 多个角色 -->
<darra-permission-gate role="admin,engineer">
<button @click="showEditDialog()">编辑参数</button>
</darra-permission-gate>
脚本权限检查
// 检查当前用户是否有指定权限
const canWrite = Darra.hasPermission('write')
const canManageUsers = Darra.hasPermission('user_manage')
// 根据权限控制 UI
if (!canWrite) {
document.getElementById('setpoint-input').disabled = true
}
权限粒度
| 权限标识 | 说明 | 默认拥有角色 |
|---|---|---|
read | 读取变量、报警 | 所有角色 |
write | 写入变量 | operator / engineer / admin |
alarm_ack | 确认报警 | operator / engineer / admin |
recipe_activate | 激活配方 | operator / engineer / admin |
recipe_edit | 编辑配方 | engineer / admin |
recipe_import | 导入配方 | admin |
recipe_export | 导出配方 | engineer / admin |
user_manage | 管理用户 | admin |
audit_view | 查看审计日志 | admin |
hmi_edit | 编辑 HMI 页面 | engineer / admin |
system_config | 修改系统配置 | admin |
sign_offline | 电子签名确认 | operator / engineer / admin |
屏幕锁定 (Screen Lock)
功能说明
HMI 长时间无人操作时自动锁定屏幕,防止误操作。锁定后需要输入密码才能解锁。
{
"ScreenLock": {
"Enabled": true,
"Timeout": 5,
"LockOnMinimize": false,
"LockOnSleep": true,
"ShowOperator": true
}
}
| 参数 | 默认值 | 说明 |
|---|---|---|
Enabled | true | 启用屏幕锁定 |
Timeout | 5 | 空闲超时(分钟) |
LockOnMinimize | false | 窗口最小化时锁定 |
LockOnSleep | true | 系统休眠/唤醒时锁定 |
ShowOperator | true | 锁屏界面是否显示当前操作员姓名 |
锁屏界面
锁屏后显示全屏覆盖层,显示当前操作员姓名、锁定时间,用户需输入密码解锁。
脚本操作
// 手动锁定
Darra.lockScreen()
// 解锁
Darra.unlockScreen(password)
// 重置空闲计时器
Darra.resetIdleTimer()
空闲超时提示
超时前 30 秒显示倒计时提示,操作员可点击"保持在线"重置计时器。超时后自动锁定。
操作审计日志
审计范围
所有影响生产安全的操作自动记录审计日志:
| 操作类别 | 记录内容 |
|---|---|
| 登录/登出 | 用户、时间、IP、结果(成功/失败) |
| 变量写入 | 用户、变量地址、写入值、原因 |
| 配方操作 | 用户、配方名、操作(激活/修改/创建/删除)、新旧值 |
| 报警确认 | 用户、报警 ID、确认时间、原因 |
| 系统配置变更 | 用户、配置项、新旧值 |
| 用户管理 | 管理员、操作类型、目标用户 |
| 电子签名 | 用户、签名类型、关联操作、签名值 |
查看审计日志
// 获取最近 100 条审计日志
const logs = Darra.getAuditLogs({ limit: 100 })
// 按时间范围筛选
const todayLogs = Darra.getAuditLogs({
startTime: Date.now() - 86400000,
endTime: Date.now(),
category: 'write', // 只查看变量写入操作
user: 'wang' // 只查看特定用户
})
// 每条日志格式
// { id, time, user, category, action, detail, ip, signature }
审计日志 UI
<darra-audit-log
category="all"
limit="50"
show-filter="true"
show-export="true"
></darra-audit-log>
日志导出
// 导出为 CSV
Darra.exportAuditLogs({
startTime: Date.now() - 7 * 86400000,
format: 'csv'
})
审计日志文件位于 %AppData%/DarraPLC/audit/ 目录,按日期分文件,只增不删,不可修改。
电子签名 (21 CFR Part 11)
适用场景
电子签名功能满足 FDA 21 CFR Part 11 合规要求,适用于医药、食品、生物制品等行业:
- 配方变更需要电子签名确认
- 关键参数修改需要电子签名
- 批量记录需要电子签名
- 审计追踪需要电子签名验证
启用电子签名
{
"ElectronicSignature": {
"Enabled": true,
"SignatureType": "username_password",
"RequireReason": true,
"RequireReview": true,
"SignatureTimeout": 30
}
}
| 参数 | 默认值 | 说明 |
|---|---|---|
Enabled | false | 启用电子签名 |
SignatureType | username_password | 签名方式:username_password / mfa / biometric |
RequireReason | true | 是否强制填写签名原因 |
RequireReview | true | 是否需要第二人复核 |
SignatureTimeout | 30 | 签名有效期(分钟),超时需重新签名 |
签名流程
操作触发签名请求
│
▼
弹出签名对话框
│
┌───┴───┐
│ 用户名 │ (自动填充当前用户)
│ 密码 │ (需重新输入)
│ 原因 │ (必填,如"调整焊接参数")
│ 复核人 │ (可选,RequireReview=true 时显示)
└───┬───┘
│
▼
验证用户名 + 密码
│
▼
记录签名日志 (含签名值、时间、原因)
│
▼
执行关联操作
签名 API
// 写入变量时要求电子签名
Darra.writeVariable('DB1.SetCurrent', 185.0, {
requireSignature: true,
reason: '工艺优化调整'
})
// 程式化签名
Darra.sign({
reason: '当前批次参数验证',
reviewer: 'li' // 复核人用户名(可选)
})
签名记录
每次电子签名生成一条不可篡改的签名记录,包含:
| 字段 | 说明 |
|---|---|
| 签名值 | 用户名 + 时间戳 + 操作内容的 HMAC 签名 |
| 签名人 | 用户名 + 显示名 |
| 签名时间 | ISO 8601 格式,精确到毫秒 |
| 签名原因 | 用户填写的签名原因 |
| 复核人 | 第二人复核的用户名(如启用) |
| 关联操作 | 本次签名授权的具体操作 |
| 签名 Hash | 整条记录的 SHA-256,链式校验 |
安全事件处理
安全事件类型
| 事件 | 级别 | 触发条件 | 自动响应 |
|---|---|---|---|
| 登录失败 | Warning | 单用户连续失败 | 锁定账户 MaxLoginAttempts 次 |
| 暴力破解 | Critical | 多用户连续失败(总次数 > 20) | 临时封禁源 IP 30 分钟 |
| 越权访问 | Error | 访问无权限的页面/API | 记录审计日志 + 返回 403 |
| 会话异常 | Warning | Token 在异地登录 | 使旧 Token 失效 |
| 白名单写入拒绝 | Info | 尝试写入未在白名单的变量 | 记录审计日志 |
| 外部认证失败 | Error | LDAP/AD 服务器无响应 | 降级到本地账户认证 |
安全事件监控
// 监听安全事件
Darra.on('securityEvent', (event) => {
// { type: 'login_fail', severity: 'warning', detail: { user: 'unknown', ip: '...' }, timestamp }
if (event.severity === 'critical') {
showSecurityAlert(event)
}
})
安全事件 API
// 获取最近的安全事件
const events = Darra.getSecurityEvents({
severity: 'error,critical',
startTime: Date.now() - 86400000,
limit: 50
})
// 清除已处理的安全事件
Darra.clearSecurityEvents({ before: Date.now() - 30 * 86400000 })
安全配置检查清单
| 项目 | 建议 | 是否强制 |
|---|---|---|
WebHMI 启用 RequireAuth | 是 | 强制 |
| 强密码策略 | 长度 ≥ 8 | 建议 |
| 会话超时 | 480 分钟以内 | 建议 |
| 登录失败锁定 | 启用 | 建议 |
| 屏幕锁定 | 启用,超时 ≤ 10 分钟 | 建议 |
| 写入白名单 | 只包含必需的变量 | 强制 |
| 审计日志 | 启用 | 建议 |
| 电子签名 | 医药/食品行业启用 | 行业合规 |
| HTTPS 部署 | 外网访问必须 | 强制 |
| 密码定期更换 | 90 天 | 建议 |
| 双因素认证 | 管理员启用 | 建议 |