Skip to content

LDAP Viewer and LDAP 登录 - #6489

Open
idxdy wants to merge 3 commits into
t8y2:mainfrom
idxdy:feat/ldap
Open

LDAP Viewer and LDAP 登录#6489
idxdy wants to merge 3 commits into
t8y2:mainfrom
idxdy:feat/ldap

Conversation

@idxdy

@idxdy idxdy commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

背景

为 DBX 增加原生 LDAP 目录浏览与登录能力,并保持与现有数据库驱动、Web 认证体系和 MCP 工具一致的可扩展边界。交互研究参考了Apache Directory Studio, 以及本人常用的交互方式

有rust原生支持方式(simple bind), 也有JNDI/JAAS的接入方式(GSSAPI), rust 下的ldap库对GSSAPI支持比较麻烦, 为了保证跨平台和兼容性, GSSAPI认证方式, 使用了java agent方式接入

登录流程、前端组件与实现代码均按 DBX 现有设计体系独立完成。

主要变更

原生 LDAP 驱动与数据层

  • 新增原生 LDAP 驱动 ldap_driver.rs(基于 ldap3 crate),支持 simple bind 与搜索,暴露与既有 Java agent 一致的 JSON 输出形态(entries/dn/attributes/count/truncated)。
  • 新增 ldap_ops.rs 统一封装搜索与子节点列举(ldap_search_core / ldap_list_children_core),支持 base/one/sub scope、RFC 4515 过滤、属性白名单与 size_limit,并对 RFC 4514/4515 转义(DN 与 filter 注入防护)。
  • DatabaseType、连接模型、连接池、schema 能力、production-safety 等扩展点登记 LDAP,接入通用连接生命周期(测试/连接/断开/关闭)。
  • 集成测试支持通过 DBX_LDAP_INTEGRATIONDBX_LDAP_HOST/PORT/USER/PASSWORD/BASE_DN 指向本地 OpenLDAP 容器(deploy/database/ldap/compose.yml + ldif/1/1.ldif,含 alice/bob/charlie 与 developers/managers 组),默认即连接 compose 环境。
  • 会自动序列化GUID字段, 方便和其他系统集成, 比如Active Role

LDAP 登录(Web 认证)

  • 新增 ldap_login.rs 登录模块,支持两种模式:
    • NOSV(无服务账号):直接以用户输入绑定。Active Directory, 支持这种方式, 一般来说支持 domain\sAMAccountName, sAMAccountName, dn, mail + password, 具体支持情况需要咨询公司的AD team的开放情况
    • SV(服务账号):先用服务账号查询用户 DN,再以用户 DN + password 绑定。openldap, 389 Directory等客户端, search 规则, 可以自己配置
  • 配置经应用设置页持久化(LdapLoginSettings),服务账号密码以脱敏方式存储、redacted() 后回传,空白时保留已存密码。
  • /auth/ldap-login 登录接口与 /auth/checkldap_enabled 联动;登录页支持 LDAP / 密码两种模式切换。
  • LDAP 登录配置接口在 /app-settings/ldap-login(含 /test 用于连接测试),统一由 auth 中间件保护。
  • test_connection 在服务账号密码留空时复用已存密码,避免“密码未配置”误报。

MCP / AI 工具

  • MCP server 新增 dbx_execute_ldap_search 工具:connection_id/name + base_dn + filter + scope + attributes[] + size_limit,仅对 LDAP 连接可用,走核心 ldap_ops::ldap_search_core,只读。
  • dbx_add_connection 支持 LDAP 专属字段(ldap_security_protocolldap_principalldap_keytab_pathldap_krb5_confldap_base_dn),并补齐默认端口 ldap→389ldaps→636
  • 应用内 AI Agent 的 dbx_execute_ldap_search 工具与 MCP 工具共用同一执行路径。

Java Agent

  • 保留并完善 LdapAgent(JNDI) 作为可选实现;LdapAgentTest 集成测试默认指向本地 OpenLDAP 容器(simple bind),GSSAPI 测试移除(无 Kerberos 环境)。
  • GSSAPI认证(Kerberos), 在公司内部测试通过, 包含 UPN + password, UPN + keytab
  • 文档路线 D 的构建产物 dbx-agent-ldap.jar 可直接替换 ~/.dbx/agents/drivers/ldap/agent.jar

安全设计

  • 未提供写入功能, 理论上来说, 企业级别的管理最好通过第三方的管理工具, 比如Active Role来做, 好吧, 我没有这个需求
  • LDAP 搜索是只读操作:dbx_execute_ldap_search 与 Agent 工具均不提供写路径,也不执行任意命令。
  • filter / DN 值统一经 RFC 4515 / RFC 4514 转义,阻止过滤注入与 RDN 注入。
  • LDAP 登录服务账号密码不落前端、不回传明文,配置读取时脱敏。
  • MCP 与 Agent 执行均经过 auth_middleware / 连接 allowlist / 只读策略约束,无绕过前端的直通路径。
  • LDAP 集成测试数据仅含本地测试目录,不含生产凭据。

自审修复

  • 登录配置接口从 /auth/* 迁移到 /app-settings/ldap-login,避免配置接口与登录接口混在同一权限域。
  • /auth/check 移除冗余的 ldap_connections,仅保留 ldap_enabled,减少未登录环境的信息暴露。
  • 默认用户搜索过滤器补全 (uid={user}),真正覆盖 AD(sAMAccountName)与 OpenLDAP(uid)。
  • test_connection 复用已存服务账号密码,修复“配置保存后测试报密码未配置”。
  • Java LdapAgentTest 集成配置改为 env 可覆盖并默认指向 compose,移除依赖真实 AD 的 GSSAPI 用例。
  • MCP bin.test 修复 Windows 下 EBUSY 临时目录清理竞态(等待子进程退出后重试删除)。

变更类型

  • 新功能
  • Bug 修复
  • 性能优化
  • 代码重构
  • 文档更新
  • CI / 构建

涉及前端

  • 本 PR 涉及前端改动,已附截图/录屏(见下方)
config search simple bind nosv pic1 gssapi keytab gssapi pwd gssapi pwd1 dark

验证

  • make dev-fast / cargo check --no-default-features:全 workspace 通过。
  • cargo test --no-default-features -p dbx-core:3475 项通过、0 失败(含 LDAP 驱动集成测试、登录过滤转义、存储往返)。
  • LDAP 集成测试(DBX_LDAP_INTEGRATION=1):simple bind 连接/搜索/size limit/属性返回 4 项全过。
  • Java Agent :ldap:test:20 项通过(simple bind 指向本地 OpenLDAP 容器)。
  • MCP pnpm test:packages:CLI + MCP-server 全部通过;dbx_execute_ldap_search 对真实目录返回 DN/属性/组信息。
  • cargo test -p dbx-web:66 项通过。
  • 前端 pnpm typecheckpnpm lint 通过;pnpm test 5708 项通过(2 项为并行 mock 竞态,单独运行该文件 32/32 通过)。
  • cargo fmt --all -- --check:通过。

关联 Issue

Related #1647

测试环境

  • deploy/database/ldap/compose.yml 提供 mlan/openldap:latest 本地容器(默认端口 389/636,ldif/1/1.ldif 自动导入),用于驱动、Java Agent 与登录流程的真实验证;rootless podman 环境需 net.ipv4.ip_unprivileged_port_start=389
  • 公司内部真实测试环境, 包含Simple Bind和GSSAPI

@github-actions github-actions Bot added area/multiple Touches more than three repository areas db/multiple Touches more than three database integrations dependencies/backend Adds a backend dependency ui-change Changes user-visible interface, text, or visual assets labels Aug 17, 2026
@idxdy idxdy changed the title LDAP View LDAP Viewer and LDAP 登录 Aug 17, 2026

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request changes:这个 head 目前不能合并。请先 rebase/split 到当前 main;GitHub 显示 3,032 个变更文件且状态为 CONFLICTING,merge-base 仍停留在 2026-04-30。

另外有三个 blocker:

  1. apps/desktop/src/lib/backend/tauri.tsldapSearch() 始终抛错,而桌面运行时会选择 Tauri backend,导致 LDAP 树、详情和搜索在桌面端全部不可用。
  2. crates/dbx-web/src/auth.rsDBX_DISABLE_PASSWORD=1 时无条件放行 API;启用 LDAP 后登录页虽要求认证,未登录请求仍能直接访问受保护接口。
  3. agents/drivers/ldap/src/main/java/com/dbx/agent/ldap/LdapAgent.java 读取 use_ssl,Core 实际发送的是 ssl,所以 GSSAPI 的 LDAPS 配置不会生效;LDAP 连接表单也没有 TLS 开关。

修复后请补 Tauri Viewer、LDAP-only middleware 和 Core→Agent TLS 映射测试,并让 exact head 的 CI 完整通过。

@idxdy

idxdy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

OK, 我处理一下

jaime.su added 3 commits August 20, 2026 14:36
Add LDAP as a first-class connection type in dbx-core:
- ldap3-based native driver (simple bind / anonymous) plus GSSAPI routing to the Java agent
- ldap_login (app-level LDAP login for the web backend) and ldap_ops (search dispatch)
- DatabaseType::Ldap + 5 ldap_* ConnectionConfig fields, pool/keepalive/health branches
- dbx-web: /ldap/search + /ldap/list-child routes, LDAP login backend, app-settings LDAP config
- storage: LDAP login settings round-trip (preserves password hash)
- agent tools: dedicated dbx_execute_ldap_search tool; LDAP excluded from SQL query paths
- LDAP browser + search components and sidebar entry tree (loadLdapRoot/loadLdapEntryChildren)
- ConnectionDialog LDAP form (simple bind / GSSAPI / anonymous, keytab + krb5.conf)
- LdapLoginSettings panel in editor settings; AppToolbar/AppTabBar LDAP-aware behavior
- QuickConnectionOpenTarget, tabPresentation and i18n (en/zh-CN) for ldap modes
- databaseNamespaceCreation / databasePropertyEditing mark LDAP as read-only browse
- api/http/tauri backend wiring for ldap search endpoints
- agents/drivers/ldap: JDBC-style Java agent for GSSAPI/Kerberos LDAP via JNDI+JAAS
- dbx-mcp: expose dbx_execute_ldap_search tool and LDAP connection options
- agents/settings.gradle: register the ldap driver module
- deploy/database/ldap: compose + ldif fixtures for local LDAP testing
@github-actions github-actions Bot added db/redis Database: Redis and removed db/multiple Touches more than three database integrations labels Aug 20, 2026
@idxdy

idxdy commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

先处理冲突问题, 之后的问题, 我会持续跟进

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/multiple Touches more than three repository areas db/redis Database: Redis dependencies/backend Adds a backend dependency ui-change Changes user-visible interface, text, or visual assets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants