跳到主内容
文档

认证与安全配置

PicoAide 认证体系 — Local、LDAP、OIDC 三种模式的完整配置和会话安全机制

PicoAide 使用 Provider 注册表模式管理认证源。系统内置 Local、LDAP、OIDC 三种认证源,通过 init() 自动注册,新增认证源无需改动核心代码。本文档详细说明每种模式的配置方法和安全机制。

认证模式概览

模式配置值用户来源密码管理适用场景
本地localSQLite 本地用户argon2id 哈希,PicoAide 管理小团队、个人部署、测试环境
LDAPldap目录服务器同步LDAP 服务器管理企业内网、已有 AD/OpenLDAP
OIDCoidcIdP 浏览器跳转登录IdP 管理SSO 平台、Keycloak/Azure AD

查看当前认证模式

GET /api/login/mode

返回当前认证模式及活跃认证源元数据。

切换认证模式

通过管理后台的「认证配置」页面或 API 修改 web.auth_mode 配置项。

切换认证模式会清除所有普通用户数据。系统会停止所有沙箱容器、归档用户目录、清空组成员关系和 IM 连接。超管账户不受影响。

本地模式 (Local)

配置

web.auth_mode = local 时使用本地认证。无需额外配置,默认即为此模式。

用户管理

  • 超管可以在管理后台手动创建/删除普通用户
  • 普通用户可以在 Web 面板修改自己的密码
  • 密码使用 argon2id 算法哈希存储(memory=19 MiB, time=2, threads=1, keyLen=32)
  • 旧版 bcrypt 密码在成功登录时自动升级为 argon2id

密码重置

picoaide reset-password <username>

只对本地用户有效。如果来源是 LDAP 或 OIDC,此命令无效。

LDAP 模式

基础配置

在管理后台或 API 中配置以下 LDAP 参数:

字段说明示例
ldap.hostLDAP 服务器地址(含端口)ldap.example.com:389
ldap.bind_dnBind DNcn=admin,dc=example,dc=com
ldap.bind_passwordBind 密码
ldap.base_dn用户搜索根 DNou=people,dc=example,dc=com
ldap.filter用户过滤器(&(objectClass=person)(uid={{username}}))
ldap.username_attribute用户名属性uid

用户登录流程

1. 用户输入用户名和密码
2. PicoAide 使用 bind_dn + bind_password 绑定 LDAP
3. 在 base_dn 范围内使用 filter 搜索用户
4. 找到用户后,使用用户的 DN 和输入的密码进行第二次绑定验证
5. 验证通过后,检查白名单(如启用)
6. 首次登录的用户自动创建本地快照和沙箱目录
7. 初始化用户工作区并异步同步组信息

白名单机制

白名单是 LDAP/OIDC 模式下的额外访问控制层:

  1. 启用白名单:设置对应源的 whitelist_enabled = true
  2. 在管理后台的白名单管理中添加允许登录的用户名
  3. 不在白名单中的用户即使认证通过也无法登录

白名单适合在迁移阶段或测试阶段限制用户范围。

组同步

PicoAide 支持两种组同步模式:

member_of 模式ldap.group_search_mode = member_of):

用户对象的 memberOf 属性直接标识所属组。适用于 Active Directory。

group_search 模式ldap.group_search_mode = group_search):

通过搜索组对象来查找成员关系。适用于 OpenLDAP。

组同步相关配置:

字段说明
ldap.group_base_dn组搜索根 DN,如 ou=groups,dc=example,dc=com
ldap.group_filter组过滤器,如 (&(objectClass=groupOfNames)(cn={{groupname}}))
ldap.group_member_attribute组成员属性,如 member

定时同步

设置 ldap.sync_interval 可以定时从 LDAP 同步用户和组。支持 Go duration 格式:

  • 30m — 每 30 分钟同步一次
  • 1h — 每小时同步一次
  • 24h — 每天同步一次
  • 0 — 关闭定时同步(默认)

也可以通过管理后台手动触发同步。

连接测试

在管理后台的认证配置页面可以测试 LDAP 连接:

  • 测试基础连接(Bind 是否成功)
  • 测试用户搜索(按用户名查找并预览结果)
  • 测试组查询(预览组和成员关系)

OIDC 模式

配置

在管理后台或 API 中配置 OIDC 参数:

字段说明示例
oidc.issuer_urlIssuer URLhttps://keycloak.example.com/auth/realms/myrealm
oidc.client_id客户端 IDpicoaide
oidc.client_secret客户端密钥
oidc.redirect_url回调地址https://picoaide.example.com/api/login/callback

登录流程

1. 用户访问登录页面,页面动态显示 SSO 登录按钮
2. 用户点击 SSO 按钮,浏览器跳转到 OIDC Provider 的认证页面
3. 用户在 Provider 侧输入凭证(如已登录则自动跳过)
4. Provider 回调到 PicoAide 的 /api/login/callback 端点
5. PicoAide 验证 state cookie、兑换授权码、验证 ID Token
6. 从 Token 中提取用户身份信息(默认使用 preferred_username)
7. 创建或更新本地用户快照
8. 异步同步组关系
9. 生成会话 Cookie,完成登录并重定向到管理面板

声明映射

OIDC Provider 返回的 ID Token 中的声明字段可以通过 oidc.username_claim 配置映射到用户名。默认使用 preferred_username

超管账户管理

超管的特点

  • 超管始终在本地存储,不依赖任何外部认证源
  • 超管优先走本地认证(即使 LDAP/OIDC 模式下也优先检查本地密码)
  • 超管不能登录浏览器扩展和桌面客户端
  • 超管不能获取 MCP Token
  • 超管访问 /user/* 会被重定向到 /admin/dashboard

创建超管

POST /api/admin/superadmins/create

返回随机生成的密码。也可以在 picoaide init 时创建初始超管。

删除超管

系统至少保留一个超管。删除最后一个超管前需要先创建新的超管。

重置超管密码

POST /api/admin/superadmins/reset

返回新的随机密码。也可以使用 CLI 命令:

picoaide reset-password <superadmin-username>

会话安全

登录成功后服务端写入 session Cookie:

Cookie: session=<username>:<timestamp>:<signature>
  • 格式:用户名:Unix时间戳:HMAC-SHA256签名
  • 有效期:24 小时
  • 属性:HttpOnlySameSite=Lax
  • TLS 启用时设置 Secure
  • 会话密钥持久化在 settings 表的 internal.session_secret 键中,重启服务后会话仍然有效

CSRF 保护

所有修改状态的 POST/PUT/PATCH 请求需要携带 csrf_token 字段。Token 获取:

GET /api/csrf

Token 机制:基于 HMAC(会话密钥, 小时窗口 + 用户名) 生成。同一小时内同一用户的 Token 不变,前一小时的 Token 也有效(容忍时钟偏差)。文件上传端点免 CSRF 检查。

速率限制

登录接口限制为 10 次/5 分钟,基于内存计数器,按 IP 隔离。超管和普通用户均受此限制。限流器包含后台过期清理 goroutine。

安全 Header

Header
X-Frame-OptionsDENY
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin

认证模式切换的数据清理

这是一个重要的安全机制。当切换认证模式时(如从 LDAP 切换到 OIDC),系统会执行 purgeOrdinaryAuthProviderStateForConfig()

  1. 停止并删除所有普通用户的沙箱容器
  2. 删除 local_users 表中所有普通用户(超管保留)
  3. 清空 groupsuser_groups
  4. 归档用户目录到 archive/
  5. 断开所有普通用户的 IM 连接

设计理由:不同认证源的用户集、组结构和权限模型完全不同。保留旧数据会导致权限混乱和状态不一致。